【问题标题】:Go polymorphism in function parameters函数参数中的 Go 多态性
【发布时间】:2014-08-25 19:28:00
【问题描述】:

我发现了几个标题相似的问题,但在其中找不到我的问题的答案:

我有以下简单的场景:

类型:

    type intMappedSortable interface {
       getIntMapping() int
    }

    type Rectangle struct {
       length, width int
    }

    func (r Rectangle) getIntMapping() int {
        return r.Area();
    }

    func (Rectangle r) getIntMapping() int {
        return r.length * r.width;
    }

主要:

func main() {
    r := rand.New(rand.NewSource(time.Now().UnixNano()))

    var values []int
    values = make([]int, 0)

    for i := 0; i < 10; i++ {
        values = append(values, r.Intn(20))
    }

    var rects []Rectangle;
    rects = make([]intMappedSortable, len(values));

    for i,v:= range values {
        r := Rectangle{v,v};
        rects[i] = r;
    }
    for i,v:= range rects {
        fmt.Println(v.Area());
    }


    rectsRet := make(chan intMappedSortable, len(rects));
    sort(rects, rectsRet);
}

做工作:

func sort(values []intMappedSortable, out chan intMappedSortable) {...}

我如何设法将 Rectangles 传递给排序函数,然后在 main 中处理排序后的矩形?

我试过了:

var rects []*Rectangle;
rects = make([]*Rectangle, len(values));

作为我C时代的习惯,我不想复制矩形,只复制地址,所以我可以直接在原始切片中排序,避免整个数据的2个复制过程。

失败后我尝试了:

var rects []intMappedSortable;
rects = make([]*Rectangle, len(values));

我了解到 Go 通过持有指向未公开的原始数据的指针来处理“多态性”,因此我将 *Rectangle 更改为 Rectangle,两者都给了我编译器错误,即 Rectangle 不是 []intMappedSortable

显然有效的是:

var rects []intMappedSortable;
rects = make([]intMappedSortable, len(values));

for i,v:= range values {
    r := Rectangle{v,v};
    rects[i] = r;
}

但是这些矩形现在是被复制了,还是只是接口的内存表示和它们的引用被复制了?此外,现在无法访问矩形的长度和宽度,因为切片不再是明确的矩形类型。

那么,我将如何实现这个场景? 我想创建一个 ANY 结构的切片,它实现 mapToInt(),对切片进行排序,然后继续使用它之后的具体类型

编辑/跟进:

我知道它的风格不好,但我正在尝试:

我能以某种方式使用动态类型的类型断言,例如:

func maptest(values []intMappedSortable, out interface{}) {
    oType := reflect.TypeOf(out);
    fmt.Println(oType); // --> chan main.intMappedSortable  
    test := values[0].(oType) //i know this is not working AND wrong even in thought because oType holds "chan intMappedSortable", but just for theory's sake
}

我怎么能这样做,或者这是不可能的。我并不是说它是否“注定要完成”,我知道它不是。但是有可能吗?^^

【问题讨论】:

  • 我建议将您的编辑作为一个独立的问题(带有指向此问题的链接以获取上下文)

标签: go polymorphism


【解决方案1】:

但是这些矩形现在是被复制了,还是只是接口的内存表示和它们的引用被复制了?

后者,见“what is the meaning of interface{} in golang?

一个接口值由两个数据字构成:

  • 一个词用于指向值的基础类型的方法表,
  • 另一个词用于指向该值所保存的实际数据。

我想创建一个 ANY 结构的切片,它实现 mapToInt(),对切片进行排序,然后继续使用它之后的具体类型

这是不可能的,因为 Go 没有通用性。
见“What would generics in Go be?

这就是为什么你有像“gen”这样的项目:

在开发时使用命令行为您的类型生成代码。
gen 不是导入;生成的源代码将成为您项目的一部分,并且没有外部依赖项。

【讨论】:

  • 回答了我的问题,谢谢。但除了不超干净,我怎么能完成我在问题中编辑的东西?
  • @billdoor 或者通过使用像 gen 这样的项目(为了使用 Rectangle),或者我进行类型断言(如在stackoverflow.com/a/20935085/6309stackoverflow.com/q/21495810/6309 中)并返回一个 Rectangle 类型来工作与。
猜你喜欢
  • 2011-01-11
  • 2021-01-28
  • 1970-01-01
  • 1970-01-01
  • 2019-10-04
  • 2016-03-19
  • 1970-01-01
  • 2017-07-17
  • 1970-01-01
相关资源
最近更新 更多