go/types, cmd/compile/internal/types2: 类型推断限制导致有向通道类型约束结果不正确

lsmepo6l  于 10个月前  发布在  Go
关注(0)|答案(3)|浏览(86)

提案详情
考虑以下代码:
可以在此处找到: https://go.dev/play/p/qNBK9KjxqrW

  1. func Chan[E any, C ~<-chan E](c C) {}
  2. func x() {
  3. c := make(chan int)
  4. Chan(c)
  5. }

然后 Chan(c) 产生 chan int does not satisfy ~<-chan int (chan int missing in ~<-chan int)
在我看来,这是通用设计中的一个缺陷,应该得到支持

t9eec4r0

t9eec4r01#

我认为这只是一个类型推断问题。
cc @griesemer

14ifxucb

14ifxucb2#

实际上,我认为我们应该能够在统一~<-chan Echan int时推导出<-chan int。正如我们多次看到的那样,在统一算法中编码这些类型的可分配规则是棘手的。但乍一看这可能并不太糟糕。

6fe3ivhb

6fe3ivhb3#

让我们考虑一个更简单的示例(没有 ~ ),但问题相同:

  1. func f[C <-chan E, E any](C) {}
  2. func _() {
  3. var c chan int
  4. f(c)
  5. }

内部讨论:@findleyr指出,代码导致了三个类型方程:

  1. C ≡A chan int (即,Cchan int 根据可分配规则匹配)
  2. C ≡C <-chan E (C 必须满足约束 <-chan E )
  3. E ≡C any
    并且有一个确切的解:C ➞ <-chan intE ➞ int 。使用这个解,代码将正常工作。
    实现使用统一化来解决这些方程。在解决方程1时,统一化推断出 C ➞ chan int 。在解决方程2时(不精确),统一化推断出 E ➞ int 。(对于方程3,没有什么要做的了。)
    由于实现一次统一一个方程,并且总是推断(最多)一个类型(例如 chan int 对于 C )而不是一组可能的类型(例如 {chan int, <-chan int, chan<- int} 对于 C ),推理在示例化失败后产生错误结果,从而导致报告的错误。
    因此,这是当前实现的一个限制。我们不太可能在不久的将来解决这个问题,因为这众所周知是困难的,而且这不是一个高优先级的问题。
    在这种情况下,可能只需使用以下替代方法编写代码 as follows :
  1. func f[E any](<-chan E) {}
  2. func _() {
  3. var c chan int
  4. f(c)
  5. }

将问题留给未来的参考/考虑。

展开查看全部

相关问题