2014-06-30 15 views
30

Tôi có một cái gì đó cấu trúc golang như thế này:Gọi chức năng golang struct cho "không thể đề cập đến lĩnh vực unexported hoặc phương pháp"

type MyStruct struct { 
    Id string 
} 

và chức năng:

func (m *MyStruct) id() { 
    // doing something with id here 
} 

Ngoài ra tôi có một cấu trúc như thế này :

type MyStruct2 struct { 
    m *MyStruct 
} 

Bây giờ tôi có một chức năng:

func foo(str *MyStruct2) { 
    str.m.id() 
} 

Nhưng tôi nhận được lỗi trong thời gian biên dịch:

str.m.id undefined (cannot refer to unexported field or method mypackage.(*MyStruct)."".id 

Làm thế nào tôi có thể gọi chức năng này một cách chính xác?

Cảm ơn bạn

Trả lời

66

Từ http://golang.org/ref/spec#Exported_identifiers:

Một định danh có thể được xuất khẩu cho phép truy cập vào nó từ một gói. Một định danh được xuất khẩu nếu cả hai:

  1. ký tự đầu tiên của tên của định danh là một Unicode chữ hoa lá thư (lớp Unicode "Lu"); và
  2. số nhận dạng được khai báo trong khối gói hoặc đó là tên trường hoặc tên phương thức.

Vì vậy, chỉ có thể sử dụng các chức năng/biến bắt đầu bằng chữ cái viết hoa ngoài gói.

Ví dụ:

type MyStruct struct { 
    id string 
} 

func (m *MyStruct) Id() { 
    // doing something with id here 
} 

//then 

func foo(str *MyStruct2) { 
    str.m.Id() 
} 
+9

đây là f ** vấn đề vua! Vì vậy, về cơ bản chỉ có các hàm/biến bắt đầu bằng --- chữ cái viết hoa --- mới có thể sử dụng được bên ngoài '. cảm ơn bạn! –

+1

Thật buồn cười khi không có bài viết nào khác nói về điều này. Tất cả đều đề xuất những cách khác nhau để vượt qua vấn đề này. Cảm ơn bạn. – rottenoats

+1

có, điều này chắc chắn phải là câu trả lời – alisa

2

Nếu bạn thay đổi MyStruct.Id-MyStruct.id, bạn sẽ không còn có thể truy cập vào nó để khởi tạo MyStruct2, bởi vì, id sẽ có thể truy cập chỉ thông qua gói riêng của mình (đó là first gói).

Điều này là do MyStructMyStruct2 nằm trong các gói khác nhau.


Để giải quyết mà bạn có thể làm điều này:

Gói first:

package first 

type MyStruct struct { 
    // `id` will be invisible outside of `first` package 
    // because, it starts with a lowercase letter 
    id string 
} 

// `Id()` is visible outside to `first` package 
// because, it starts with an uppercase letter 
func (m *MyStruct) Id() string { 
    return m.id 
} 

// Create a constructor function to return `*MyStruct` 
func NewMyStruct(id string) *MyStruct { 
    return &MyStruct{ 
     id: id, 
    } 
} 

Gói second:

package second 

// Import MyStruct's package 
import "first" 

type MyStruct2 struct { 
    // If you don't use `m` here as in your question, 
    // `first.MyStruct` will be promoted automatically. 
    // 
    // So, you can reach its methods directly, 
    // as if they're inside `MyStruct2` 
    *first.MyStruct 
} 

// You can use `Id()` directly because it is promoted 
// As if, inside `MyStruct2` 
func foo(str *MyStruct2) { 
    str.Id() 
} 

// You can initialize `MyStruct2` like this: 
func run() { 
    foo(&MyStruct2{ 
     MyStruct: first.NewMyStruct("3"), 
    }) 
} 
Các vấn đề liên quan