英文:
reusing the methods of the base type in the derived custom type in golang
问题
我想在sort.IntSlice
上创建一个ReverseSort
方法。所以我创建了一个名为MySlice
的自定义类型,并为其添加了一个ReverseSort
方法。
package main
import (
"fmt"
"sort"
)
type MySlice sort.IntSlice
func (ms MySlice) ReverseSort() {
sort.Sort(sort.Reverse(ms))
}
func main() {
t2 := MySlice{5, 4, 3, 1}
t2.ReverseSort()
fmt.Println(t2)
}
但是运行这个程序时出现了错误:
cannot use ms (type MySlice) as type sort.Interface in argument to sort.Reverse:
MySlice does not implement sort.Interface (missing Len method)
有没有一种方法可以在不为我的自定义类型创建Len
、Swap
和Less
方法的情况下实现这个功能?
英文:
i want to create a ReverseSort
method on sort.IntSlice
. So i created a custom type of MySlice
and added a method of ReverseSort
to it.
package main
import (
"fmt"
"sort"
)
type MySlice sort.IntSlice
func (ms MySlice) ReverseSort() {
sort.Sort(sort.Reverse(ms))
}
func main() {
t2 := MySlice{5, 4, 3, 1}
t2.ReverseSort()
fmt.Println(t2)
}
But on running this program error is shown that
cannot use ms (type MySlice) as type sort.Interface in argument to sort.Reverse:
MySlice does not implement sort.Interface (missing Len method)
Is there a way by which i can implement this without creating my own Len
, Swap
and Less
methods for my custom type.
答案1
得分: 5
你可以在自定义类型中嵌入sort.IntSlice
:
type MySlice struct {
sort.IntSlice
}
func (ms MySlice) ReverseSort() {
sort.Sort(sort.Reverse(ms))
}
func main() {
t2 := MySlice{sort.IntSlice{5, 4, 3, 1}}
t2.ReverseSort()
fmt.Println(t2)
}
(在Go Playground上)
当然,这样做会使对象的构造更加困难。
在golang-nuts的帖子中讨论了这个问题:
按设计,您“不能在非本地类型上定义新方法”。
最佳实践是将非本地类型嵌入到您自己的本地类型中,并进行扩展。类型别名(type MyFoo Foo)创建了一个与原始类型(more-or-less)完全不同的类型。我不知道有没有一种直接/最佳实践的方法可以使用类型断言来解决这个问题。
- Peter Bourgon
还有:
类型的方法在定义它的包中。
这是一种逻辑上的一致性。它是一种编译优势。它被视为大规模维护和多人开发项目的重要优势。
你所说的能力并没有丧失,因为你可以像上面描述的那样将基本类型嵌入到新类型中,并添加任何你想要的内容,以实现你所寻求的“is a”功能,唯一的限制是你的新类型必须有一个新的名称,并且它的所有字段和方法必须在它的新包中。
- Michael Jones
英文:
You could embed sort.IntSlice
in your custom type:
type MySlice struct {
sort.IntSlice
}
func (ms MySlice) ReverseSort() {
sort.Sort(sort.Reverse(ms))
}
func main() {
t2 := MySlice{sort.IntSlice{5, 4, 3, 1}}
t2.ReverseSort()
fmt.Println(t2)
}
(On the Go Playgroud.)
Of course, that makes constructing objects more difficult.
A post on golang-nuts discusses this:
> You "cannot define new methods on non-local type
>
> The best practice is to embed the non-local type into your own own
> local type, and extend it. Type-aliasing (type MyFoo Foo) creates a
> type that is (more-or-less) completely distinct from the original. I'm
> not aware of a straightforward/best-practice way to use type
> assertions to get around that.
>
> - Peter Bourgon
And:
> > A type's methods are in the package that defines it.
>
> This is a logical coherence. It is a compilation virtue. It is seen as
> an important benefit for large-scale maintenance and multi-person
> development projects.
>
> The power you speak of is not lost, though, because you can embed the
> base type in a new type as described above and add whatever you want
> to it, in the kind of functional "is a" that you seek, with the only
> caveat that your new type must have a new name, and all of its fields
> and methods must be in its new package.
>
> - Michael Jones
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论