我有一个接口模型
,它是由structPerson
实现的。
要获取模型实例,我有以下助手函数:
func newModel(c string) Model {
switch c {
case "person":
return newPerson()
}
return nil
}
func newPerson() *Person {
return &Person{}
}
上述方法允许我返回一个正确类型的Person实例(以后可以使用相同的方法轻松添加新模型)。
当我尝试执行类似的操作以返回模型片段时,我得到了一个错误。代码:
func newModels(c string) []Model {
switch c {
case "person":
return newPersons()
}
return nil
}
func newPersons() *[]Person {
var models []Person
return &models
}
Go抱怨:不能在返回参数
中使用newPeople()(type[]Person)作为type[]Model
我的目标是返回所请求的任何模型类型的切片(无论是[]Person
,[]FutureModel
,[]Terminator2000
,w/e)。我遗漏了什么?我如何才能正确实施这样的解决方案?
因为斯蒂芬已经回答了这个问题,你是初学者,所以我强调给出建议。
使用go接口的更好方法不是让构造函数返回接口,就像您在其他语言(如java)中使用的那样,而是让每个对象都有一个独立的构造函数,因为它们隐式地实现接口。
而不是
newModel(type string) Model { ... }
你应该这样做
newPerson() *Person { ... }
newPolitician() *Politician { ... }
与Person
和political
一起实现Model
的方法。您仍然可以在接受模型的任何地方使用
Person
或political
,但也可以实现其他接口。
在手动转换到另一种接口类型之前,使用您的方法只能使用
Model
。
假设我有一个
Person
实现了方法Walker()
和一个Model
实现了Showoff()
,以下内容将无法直接执行:
newModel("person").ShowOff()
newModel("person").Walk() // Does not compile, Model has no method Walk
然而,这将:
newPerson().ShowOff()
newPerson().Walk()
也许这是您的返回类型*[]Person
的问题,它实际上应该是[]*Person
,以便引用切片的每个索引都是对Person
的引用,并且切片[]
本身是对数组的引用。
请查看以下示例:
package main
import (
"fmt"
)
type Model interface {
Name() string
}
type Person struct {}
func (p *Person) Name() string {
return "Me"
}
func NewPersons() (models []*Person) {
return models
}
func main() {
var p Model
p = new(Person)
fmt.Println(p.Name())
arr := NewPersons()
arr = append(arr, new(Person))
fmt.Println(arr[0].Name())
}
这很像我刚才回答的一个问题:https://stackoverflow.com/a/12990540/727643
简而言之,你是对的。结构的切片不等于结构实现的接口的切片。
[]个人
和[]型号
具有不同的内存布局。这是因为它们所属的类型具有不同的内存布局。一个模型
是一个接口值,这意味着在内存中它的大小是两个字。一个字表示类型信息,另一个字表示数据。Person
是一个结构,其大小取决于它包含的字段。为了将[]个人
转换为[]模型
,您需要在数组上循环并对每个元素进行类型转换。
由于此转换是一个O(n)操作,并且会导致创建一个新的切片,所以Go拒绝隐式地进行转换。您可以使用以下代码显式地执行此操作。
models := make([]Model, len(persons))
for i, v := range persons {
models[i] = Model(v)
}
return models
正如dskner所指出的,您很可能想要一个指针片段,而不是一个指向片段的指针。通常不需要指向切片的指针。
*[]Person // pointer to slice
[]*Person // slice of pointers
问题内容: 我有一个接口,该接口由struct实现。 要获取模型实例,我具有以下辅助函数: 上面的方法允许我返回正确类型的Person实例(以后可以使用相同的方法轻松添加新模型)。 当我尝试执行类似的操作以返回模型切片时,出现错误。码: 去抱怨: 我的目标是回到请求任何机型的切片(是否,,,W / E)。我缺少什么,如何正确实施这样的解决方案? 问题答案: 简短的答案是您是正确的。结构的片段不等于
问题内容: 给定您具有接受功能的场景。如果确定是切片,我如何在该切片上? 前往游乐场示例:http://play.golang.org/p/DNldAlNShB 问题答案: 好吧,我曾经使用过,然后如果它是一个切片,则可以调用,并在该值上调用以在索引处获取切片和元素的。我认为您将无法使用范围操作来做到这一点。 前往游乐场示例:http : //play.golang.org/p/gQhCTiwPA
本文向大家介绍C#结构实现接口,包括了C#结构实现接口的使用技巧和注意事项,需要的朋友参考一下 示例
问题内容: 我不理解以下代码的行为。在创建作为结构指针切片的匹配结构列表时,代码始终会打印原始数组的最后一个元素(实际上不是匹配项),它会打印12和12。但是,如果将匹配项更改为[]窗口小部件代替[] * Widget,然后将输出10和11。 为什么是这样? 问题答案: 那是因为当您使用指针时,您将添加到数组。 请注意,实际上这是循环中使用的局部变量,因此,这不是您要添加到数组中的地址。 (即使变
问题内容: 我将如何为正在实现接口的内部类编写构造函数?我知道我可以上一门全新的课,但是我认为必须有一种方法可以做到这一点: 当我输入此内容时,它不会将AbstractAction方法识别为构造函数(编译器要求返回类型)。有人有主意吗? 问题答案: 只需在扩展类的名称后面插入参数即可: 另外,您可以使用初始化块:
我也试过: 它可以在其他Kotlin文件中工作(我可以编写),但我必须用Java编写。这个解决方案似乎最接近我想要的。 有什么解决办法吗?我希望能够用Kotlin和Java编写,并让它们引用一个实现接口的对象。 我相信我也可以将我的接口转换成一个抽象类,但这是最后的手段。