มีคำตอบ / เทคนิคหลายประการสำหรับคำถามด้านล่าง:
- จะตั้งค่าเริ่มต้นเป็นโครงสร้าง golang ได้อย่างไร?
 - วิธีการเริ่มต้นโครงสร้างใน golang
 
ฉันมีคำตอบสองสามข้อ แต่จำเป็นต้องมีการอภิปรายเพิ่มเติม
มีคำตอบ / เทคนิคหลายประการสำหรับคำถามด้านล่าง:
ฉันมีคำตอบสองสามข้อ แต่จำเป็นต้องมีการอภิปรายเพิ่มเติม
คำตอบ:
แนวคิดหนึ่งที่เป็นไปได้คือการเขียนฟังก์ชันตัวสร้างแยกต่างหาก
//Something is the structure we work with
type Something struct {
     Text string 
     DefaultText string 
} 
// NewSomething create new instance of Something
func NewSomething(text string) Something {
   something := Something{}
   something.Text = text
   something.DefaultText = "default text"
   return something
}
    NewSomethingและแม้กระทั่งฟิลด์Textและแต่ก็ไม่ได้ส่งออกประเภทที่DefaultText struct something
                    reflect.New()เป็นต้น) คาดว่าจะไม่ทราบเกี่ยวกับฟังก์ชันโรงงานที่มีชื่อพิเศษของคุณ ในกรณีนั้นและการเปลี่ยนภาษาสั้น ๆ เองฉันคิดว่ามีเพียงอินเทอร์เฟซ (ที่ไลบรารีตรวจสอบได้)
                    บังคับเมธอดเพื่อรับโครงสร้าง (วิธีตัวสร้าง)
จากโพสต์นี้ :
การออกแบบที่ดีคือการทำให้ประเภทของคุณไม่ถูกส่งออก แต่ให้ฟังก์ชันตัวสร้างที่ส่งออก
NewMyType()ซึ่งคุณสามารถเริ่มต้นโครงสร้าง / ประเภทของคุณได้อย่างถูกต้อง ส่งคืนประเภทอินเทอร์เฟซไม่ใช่ประเภทคอนกรีตและอินเทอร์เฟซควรมีทุกสิ่งที่คนอื่นต้องการทำกับคุณค่าของคุณ และประเภทคอนกรีตของคุณต้องใช้อินเทอร์เฟซนั้นแน่นอน
ซึ่งสามารถทำได้โดยการทำให้ชนิดไม่ถูกส่งออก คุณสามารถส่งออกฟังก์ชัน NewSomething และแม้แต่ช่อง Text และ DefaultText ได้ แต่อย่าส่งออกโครงสร้างบางอย่าง
อีกวิธีหนึ่งในการปรับแต่งสำหรับโมดูลของคุณเองคือการใช้Config struct เพื่อตั้งค่าเริ่มต้น (ตัวเลือกที่ 5 ในลิงค์) ไม่ใช่วิธีที่ดีแม้ว่า
ปัญหาหนึ่งของตัวเลือกที่ 1 ในคำตอบจาก Victor Zamanian คือหากไม่ได้ส่งออกประเภทดังกล่าวผู้ใช้แพ็คเกจของคุณจะไม่สามารถประกาศว่าเป็นประเภทสำหรับพารามิเตอร์ฟังก์ชันได้วิธีหนึ่งในการแก้ไขปัญหานี้คือการส่งออกอินเทอร์เฟซแทน โครงสร้างเช่น
package candidate
// Exporting interface instead of struct
type Candidate interface {}
// Struct is not exported
type candidate struct {
    Name string
    Votes uint32 // Defaults to 0
}
// We are forced to call the constructor to get an instance of candidate
func New(name string) Candidate {
    return candidate{name, 0}  // enforce the default value here
}
ซึ่งช่วยให้เราสามารถประกาศประเภทพารามิเตอร์ของฟังก์ชันโดยใช้อินเทอร์เฟซผู้สมัครที่ส่งออก ข้อเสียเดียวที่ฉันเห็นจากโซลูชันนี้คือวิธีการทั้งหมดของเราจำเป็นต้องได้รับการประกาศในคำจำกัดความของอินเทอร์เฟซ แต่คุณสามารถโต้แย้งได้ว่านั่นเป็นแนวทางปฏิบัติที่ดี
มีวิธีการทำเช่นนี้กับแท็กซึ่งอนุญาตให้มีค่าเริ่มต้นหลายค่า
สมมติคุณมี struct ต่อไปนี้มี 2 เริ่มต้นแท็กdefault0และdefault1
type A struct {
   I int    `default0:"3" default1:"42"`
   S string `default0:"Some String..." default1:"Some Other String..."`
}
ตอนนี้สามารถตั้งค่าเริ่มต้นได้
func main() {
ptr := &A{}
Set(ptr, "default0")
fmt.Printf("ptr.I=%d ptr.S=%s\n", ptr.I, ptr.S)
// ptr.I=3 ptr.S=Some String...
Set(ptr, "default1")
fmt.Printf("ptr.I=%d ptr.S=%s\n", ptr.I, ptr.S)
// ptr.I=42 ptr.S=Some Other String...
}
นี่คือโปรแกรมที่สมบูรณ์ในสนามเด็กเล่น
หากคุณสนใจในตัวอย่างที่ซับซ้อนมากขึ้นให้พูดโดยใช้ชิ้นส่วนและแผนที่จากนั้นดูที่creasty / defaultse
จากhttps://golang.org/doc/effective_go.html#composite_literals :
บางครั้งค่าศูนย์ไม่ดีพอและจำเป็นต้องมีการเตรียมใช้งานคอนสตรัคเตอร์เนื่องจากในตัวอย่างนี้ได้มาจากระบบปฏิบัติการแพคเกจ
    func NewFile(fd int, name string) *File {
      if fd < 0 {
        return nil
      }
      f := new(File)
      f.fd = fd
      f.name = name
      f.dirinfo = nil
      f.nepipe = 0
      return f
}
    type Config struct {
    AWSRegion                               string `default:"us-west-2"`
}