如何解决“接口方法不能有类型参数”的问题?

huangapple go评论82阅读模式
英文:

How to solve "interface method must have no type parameters"?

问题

我正在尝试在1.18beta2中使用go泛型,并尝试为键值存储(boltdb)编写一个抽象层。这是我想要实现的效果。

type Reader interface {
	Read(bucket []byte, k ...[]byte) ([][]byte, error)
	ReadDoc[V Unmarshaler](bucket []byte, factory func() (V, error), k ...[]byte) ([]V, error)
}

type Unmarshaler interface {
	UnmarshalKV(v []byte) error
}

这样,当找到一个键/值时,我可以提供一个工厂来创建该类型,将数据解组到其中,并返回该特定类型的切片。但是编译器给出了"interface method must have no type parameters"的错误。为什么接口中不允许有类型参数?是否计划支持这个功能?这让我感到沮丧...本来会很完美的。不过,它确实可以在接口外部工作。

英文:

I'm trying out go generics in 1.18beta2 and I'm trying to write an abstraction layer for key/value store, boltdb. This is what I'm trying to achieve with it.

type Reader interface {
	Read(bucket []byte, k ...[]byte) ([][]byte, error)
	ReadDoc[V Unmarshaler](bucket []byte, factory func() (V, error), k ...[]byte) ([]V, error)
}

type Unmarshaler interface {
	UnmarshalKV(v []byte) error
}

So that I can provide it a factory to create the type when it finds a key/value, unmarshal the data into it and return back a slice of that specific type. Only I get "interface method must have no type parameters" from the compiler. Why are't type parameters allowed in interfaces? Is supporting this planned? This has crushed my dreams... Would have been perfect. It does however work out of interface.

答案1

得分: 10

今天早些时候遇到了同样的问题。这似乎是泛型/类型参数的设计决策,因为在接口定义(和实现工作)中可能有多种解释方法。

在某些情况下,可能意味着:

  • 参数的身份不被保留。
  • 需要在编译时遍历整个树,这会影响性能。
  • 需要在运行时进行反射,这会影响性能。
  • 参数化方法不实现接口,这会导致混淆。

更多信息请参阅Type parameters proposal, No parametrized methods

但是,你可以将类型参数移到接口类型定义中。Proposal, Very high level overview

type Reader[V Unmarshaler] interface {
    Read(bucket []byte, k ...[]byte) ([][]byte, error)
    ReadDoc(bucket []byte, factory func() (V, error), k ...[]byte) ([]V, error)
}

type Unmarshaler interface {
    UnmarshalKV(v []byte) error
}
英文:

Ran into the same issue earlier today. This seems to be a design decision for the generics/type parameters since there could be multiple "ways" of interpreting a method with type parameters in interface definition (and implementation work).

In some cases it could either mean:

  • Identity of the argument is not preserved.
  • Need to traverse the whole tree at compile time, which impacts performance.
  • Need for reflection at runtime, which impacts performance.
  • Parametrized method do not implement interfaces, which would lead to confusion.

More information in the Type parameters proposal, No parametrized methods

You could however move the type parameter into the interface type definition. Proposal, Very high level overview:

type Reader[V Unmarshaler] interface {
    Read(bucket []byte, k ...[]byte) ([][]byte, error)
    ReadDoc(bucket []byte, factory func() (V, error), k ...[]byte) ([]V, error)
}

type Unmarshaler interface {
    UnmarshalKV(v []byte) error
}

huangapple
  • 本文由 发表于 2022年2月16日 03:15:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/71132124.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定