Khởi tạo một cấu trúc lồng nhau


124

Tôi không thể tìm ra cách khởi tạo một cấu trúc lồng nhau. Tìm ví dụ tại đây: http://play.golang.org/p/NL6VXdHrjh

package main

type Configuration struct {
    Val   string
    Proxy struct {
        Address string
        Port    string
    }
}

func main() {

    c := &Configuration{
        Val: "test",
        Proxy: {
            Address: "addr",
            Port:    "80",
        },
    }

}

1
Chỉ cần học đi và có cùng một câu hỏi. Bạn có thể bỏ qua các kiểu phần tử cho mảng và bản đồ nhưng không cho các cấu trúc lồng nhau. Phi logic và bất tiện. Ai đó có thể giải thích tại sao?
Peter Dotchev

Câu trả lời:


177

Chà, có lý do cụ thể nào để không tạo cấu trúc riêng cho Proxy không?

Dù sao bạn có 2 lựa chọn:

Cách thích hợp, chỉ cần di chuyển proxy đến cấu trúc của chính nó, ví dụ:

type Configuration struct {
    Val string
    Proxy Proxy
}

type Proxy struct {
    Address string
    Port    string
}

func main() {

    c := &Configuration{
        Val: "test",
        Proxy: Proxy{
            Address: "addr",
            Port:    "port",
        },
    }
    fmt.Println(c)
    fmt.Println(c.Proxy.Address)
}

Cách ít phù hợp và xấu xí nhưng vẫn hoạt động:

c := &Configuration{
    Val: "test",
    Proxy: struct {
        Address string
        Port    string
    }{
        Address: "addr",
        Port:    "80",
    },
}

1
Trong phương pháp thứ hai, chúng ta có thể tránh định nghĩa cấu trúc lặp lại không?
Gaurav Ojha

@GauravOjha không phải là tất cả, nhưng một cái gì đó giống như play.golang.org/p/n24BD3NlIR
OneOfOne

Tôi nghĩ rằng việc sử dụng kiểu nhúng phù hợp hơn với mối quan hệ là mối quan hệ.
crackerplace

như được chỉ ra bên dưới bởi @sepehr, bạn có thể truy cập trực tiếp các biến bằng cách sử dụng ký hiệu dấu chấm.
snassr

Điều gì sẽ xảy ra nếu proxy có một trường với struct as type? Làm cách nào để khởi tạo chúng bên trong một cấu trúc lồng nhau khác?
kucinghitam

90

Nếu bạn không muốn đi với định nghĩa cấu trúc riêng biệt cho cấu trúc lồng nhau và bạn không thích phương pháp thứ hai do @OneOfOne đề xuất, bạn có thể sử dụng phương pháp thứ ba này:

package main
import "fmt"
type Configuration struct {
    Val   string
    Proxy struct {
        Address string
        Port    string
    }
}

func main() {
    c := &Configuration{
        Val: "test",
    }

    c.Proxy.Address = `127.0.0.1`
    c.Proxy.Port = `8080`
}

Bạn có thể kiểm tra nó tại đây: https://play.golang.org/p/WoSYCxzCF2


8
Chà, một câu trả lời thực tế cho câu hỏi về cách khởi tạo các cấu trúc lồng nhau .
Tối đa

1
Điều này thực sự khá tốt, nhưng sẽ tốt hơn nếu chúng ta có thể làm điều đó trong một dòng!
Gaurav Ojha

1
Tôi đang tìm một cách mà bạn không cần phải làm c.Proxy.Address = `127.0.0.1` c.Proxy.Port = `8080` Có cách nào để khởi tạo những giá trị đó trong quá trình &Configuration{}gán không?
Matheus Felipe

1
@MatheusFelipe bạn có thể nhưng sau đó bạn phải xác định Proxylà cấu trúc của riêng nó, hãy xem phương pháp đầu tiên trong câu trả lời của @OneOfOne
sepehr

IMO, điều này tốt hơn câu trả lời được chấp nhận.
domoarigato

14

Xác định Proxycấu trúc của bạn một cách riêng biệt, bên ngoài Configuration, như sau:

type Proxy struct {
    Address string
    Port    string
}

type Configuration struct {
    Val string
    P   Proxy
}

c := &Configuration{
    Val: "test",
    P: Proxy{
        Address: "addr",
        Port:    "80",
    },
}

Xem http://play.golang.org/p/7PELCVsQIc


Nếu P Proxylà một mảng thì sao?
Ertuğrul Altınboğa

10

Bạn cũng có tùy chọn này:

type Configuration struct {
        Val string
        Proxy
}

type Proxy struct {
        Address string
        Port    string
}

func main() {
        c := &Configuration{"test", Proxy{"addr", "port"}}
        fmt.Println(c)
}

Có hoặc tương tự với loại trường
Pierrick HYMBERT 27/02

Nếu Proxylà một mảng thì sao?
Ertuğrul Altınboğa

9

Một gotcha nảy sinh khi bạn muốn khởi tạo một kiểu công khai được xác định trong một gói bên ngoài và kiểu đó nhúng các kiểu riêng tư khác.

Thí dụ:

package animals

type otherProps{
  Name string
  Width int
}

type Duck{
  Weight int
  otherProps
}

Làm thế nào để bạn khởi tạo một Duckchương trình của riêng bạn? Đây là điều tốt nhất tôi có thể nghĩ ra:

package main

import "github.com/someone/animals"

func main(){
  var duck animals.Duck
  // Can't instantiate a duck with something.Duck{Weight: 2, Name: "Henry"} because `Name` is part of the private type `otherProps`
  duck.Weight = 2
  duck.Width = 30
  duck.Name = "Henry"
}

Đối với những người hay quên như tôi, hãy đặt tên các thuộc tính struct của bạn bằng chữ in hoa, nếu không, bạn sẽ gặp cannot refer to unexported field or method lỗi.
tagaism

5

Bạn cũng có thể phân bổ bằng cách sử dụng newvà khởi tạo tất cả các trường bằng tay

package main

type Configuration struct {
    Val   string
    Proxy struct {
        Address string
        Port    string
    }
}

func main() {
    c := new(Configuration)
    c.Val = "test"
    c.Proxy.Address = "addr"
    c.Proxy.Port = "80"
}

Xem trong sân chơi: https://play.golang.org/p/sFH_-HawO_M


2

Bạn có thể xác định một cấu trúc và tạo đối tượng của nó trong một cấu trúc khác như tôi đã làm dưới đây:

package main

import "fmt"

type Address struct {
    streetNumber int
    streetName   string
    zipCode      int
}

type Person struct {
    name    string
    age     int
    address Address
}

func main() {
    var p Person
    p.name = "Vipin"
    p.age = 30
    p.address = Address{
        streetName:   "Krishna Pura",
        streetNumber: 14,
        zipCode:      475110,
    }
    fmt.Println("Name: ", p.name)
    fmt.Println("Age: ", p.age)
    fmt.Println("StreetName: ", p.address.streetName)
    fmt.Println("StreeNumber: ", p.address.streetNumber)
}

Hy vọng nó đã giúp bạn :)


2

Bạn cần xác định lại cấu trúc không tên trong &Configuration{}

package main

import "fmt"

type Configuration struct {
    Val   string
    Proxy struct {
        Address string
        Port    string
    }
}

func main() {

    c := &Configuration{
        Val: "test",
        Proxy: struct {
            Address string
            Port    string
        }{
            Address: "127.0.0.1",
            Port:    "8080",
        },
    }
    fmt.Println(c)
}

https://play.golang.org/p/Fv5QYylFGAY

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.