如何创建扩展类型

时间:2018-09-18 19:06:32

标签: go

我看到可以扩展导入的包,例如添加新方法。

但是,我尝试使用此方法创建自己的结构的新实例:

package main

import (
    "github.com/intdxdt/rtree"
)

type RTree struct {
    rtree.RTree
}

func NewRTree(nodeCap ...int) *RTree {
    return rtree.NewRTree(nodeCap...)
}

我在其他问题上看到了类似的例子。但是我得到一个错误:不能在返回参数中使用rtree.NewRTree(nodeCap ...)(类型* rtree.RTree)作为类型* RTree

问题是-我该如何初始化我的结构并将其与自己的方法一起使用,并包括所有导入的方法/字段?

1 个答案:

答案 0 :(得分:2)

Always remember, Go doesn't support inheritance. It supports composition.

You may call it inheritance, as far as it helps you to logically map between other OOP languages, and Go. Rule of thumb, whenever something doesn't work the way it works in OOP world, think in terms of composition.

But when it comes to writing actual code, always remember that there is no is a relationship in composition, and it's always has a, even if it seems otherwise, because of the fact that you can actually access the member variables and methods of the composed/embedded(still, not inherited) struct. You can even override the method, if you declare the same with the new struct. Here's another catch - You still won't be able to access un-exposed (close to protected from Java-world) variables and functions of a struct in another package, as it seems in your case.

But, your type RTree has rtree.RTree, but is never going to be a rtree.RTree, and will always be a different type for the compiler.

package main

import (
    "github.com/intdxdt/rtree"
)

type RTree struct {
    rtree.RTree
}

func NewRTree(nodeCap ...int) *RTree {
    return &RTree{
        RTree: *rtree.NewRTree(nodeCap...),
    }
}

On a separate node, unless you have more parameters to add, why not use rtree.RTree directly? Composing it, will give you all the methods of the enclosing type, but you can't pass it to any function that expects the enclosing type. Good news is, you will implicitly satisfy the interfaces that enclosing type satisfies, and hence you can pass it to functions that accept those interfaces.