英文:
Defined public properties on a struct can not be accessed implementing interface
问题
有一个接口Comment,必须实现才能被包功能访问。尽管实现了接口并创建了一个CommentTest对象的切片,但是将Comment作为项类型,使得Title属性无法访问。PS:在这种情况下,Stringer函数可以正常工作。有没有一种方法可以在不进行类型断言的情况下使其工作?
package main
import "fmt"
type Comment interface {
SetChild(Comment)
GetChildren() []Comment
GetID() int
GetParentID() int
}
type CommentTest struct {
Title string
ID int
ParentID int
Children []Comment
}
func (ct *CommentTest) SetChild(c Comment) {
ct.Children = append(ct.Children, c)
}
func (ct CommentTest) GetChildren() []Comment {
return ct.Children
}
func (ct CommentTest) GetID() int {
return ct.ID
}
func (ct CommentTest) GetParentID() int {
return ct.ParentID
}
// works well, all public properties are 100% accesible
func (ct CommentTest) String() string {
return "{ID: " + strconv.Itoa(ct.ID) + ", ParentID: " + strconv.Itoa(ct.ParentID) + ", Title: " + ct.Title + "}"
}
/*
There are test comments with this structure:
1 ->
2 ->
4
3 ->
5
*/
func testData() (Comment, []Comment) {
var plain []Comment
root := &CommentTest{ID: 1, ParentID: 3, Title: "Test 1"} // ParentID 3 -> Check for infinite recursion
plain = append(plain, root)
plain = append(plain, &CommentTest{ID: 2, ParentID: 1, Title: "Test 2"})
plain = append(plain, &CommentTest{ID: 3, ParentID: 1, Title: "Test 3"})
plain = append(plain, &CommentTest{ID: 4, ParentID: 2, Title: "Test 4"})
plain = append(plain, &CommentTest{ID: 5, ParentID: 3, Title: "Test 5"})
return root, plain
}
func main() {
root, plain := testData()
fmt.Println(root) // works well
root.Title //root.Title undefined (type Comment has no field or method Title)
}
英文:
There is an interface Comment that has to be implemented in order to be accessible by a package functionality. Though implementing the interface and then making a slice of CommentTest objects but with Comment as items type makes the Title public property undefined. PS: Stringer works fine in this case. Is there a way to make it work without type assertion?
package main
import "fmt"
type Comment interface {
SetChild(Comment)
GetChildren() []Comment
GetID() int
GetParentID() int
}
type CommentTest struct {
Title string
ID int
ParentID int
Children []Comment
}
func (ct *CommentTest) SetChild(c Comment) {
ct.Children = append(ct.Children, c)
}
func (ct CommentTest) GetChildren() []Comment {
return ct.Children
}
func (ct CommentTest) GetID() int {
return ct.ID
}
func (ct CommentTest) GetParentID() int {
return ct.ParentID
}
// works well, all public properties are 100% accesible
func (ct CommentTest) String() string {
return "{ID: " + strconv.Itoa(ct.ID) + ", ParentID: " + strconv.Itoa(ct.ParentID) + ", Title: " + ct.Title + "}"
}
/*
There are test comments with this structure:
1 ->
2 ->
4
3 ->
5
*/
func testData() (Comment, []Comment) {
var plain []Comment
root := &CommentTest{ID: 1, ParentID: 3, Title: "Test 1"} // ParentID 3 -> Check for infinite recursion
plain = append(plain, root)
plain = append(plain, &CommentTest{ID: 2, ParentID: 1, Title: "Test 2"})
plain = append(plain, &CommentTest{ID: 3, ParentID: 1, Title: "Test 3"})
plain = append(plain, &CommentTest{ID: 4, ParentID: 2, Title: "Test 4"})
plain = append(plain, &CommentTest{ID: 5, ParentID: 3, Title: "Test 5"})
return root, plain
}
func main() {
root, plain := testData()
fmt.Println(root) // works well
root.Title //root.Title undefined (type Comment has no field or method Title)
}
答案1
得分: 2
变量root
的类型是Comment
,它是一个接口,因此它是一组方法。它没有任何成员变量。
你可以做以下几件事情:
- 如你所提到的,使用类型断言。
- 在
CommentTest
中添加一个GetTitle()
方法,并使用一个单独的接口:
type titler interface { GetTitle() string }
if t, ok := root.(titler); ok {
t.GetTitle()
}
英文:
The variable root
is of type Comment
, which is an interface, thus, it is a set of methods. It does not have any member variables.
There are several things you can do:
- Use type assertion, as you mentioned.
- Add a GetTitle() method to CommentTest, and use a separate interface:
type titler interface { GetTitle() string }
if t, ok:=root.(titler); ok {
t.GetTitle()
}
答案2
得分: 1
接口只提供对方法的访问,而不提供对字段的访问(它们对于隐藏在其后面的字段布局或是否为结构体都是不可知的)。您可以向接口添加一个GetTitle()
方法,并使用它。
英文:
Interfaces only provide access to methods, not fields (they're agnostic to the field layout of whatever hides behind them, or whether it's even a struct). You can add a GetTitle()
method to the interface, and use that.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论