【发布时间】:2021-06-19 14:48:37
【问题描述】:
我正在尝试创建一个高阶函数,它对输入函数接受的参数类型有一个上限。
展示问题的幼稚尝试的玩具示例:
class A
class B extends A
def AFunc(f: A => Unit): Unit = {}
AFunc((b: B) => {})
//<console>:14: error: type mismatch;
// found : B => Unit
// required: A => Unit
// AFunc((b: B) => {})
我认为这不起作用,因为函数的参数是逆变的,所以 B => Unit 是 A => Unit 的超类型。
有可能让它与像这样的多态函数一起工作:
class A
class B extends A
def AFunc[T <: A](f: T => Unit): Unit = {}
AFunc[B]((b: B) => {})
这个解决方案的缺点是要求调用者知道传递函数参数的确切类型,尽管所有 AFunc 关心的类型是它是 A 的子类型。
有没有一种类型安全的方法可以在不显式传递类型的情况下强制执行类型约束?
【问题讨论】:
-
嗯,你不可能不知道参数的类型,因为你是 将它传入 :) 也许,你的意思是必须在调用时明确地拼出类型网站,但您实际上并不需要这样做,只需
AFunc((b: B) => {})即可。 -
哦,哇,确实有效!我觉得有点傻。我想,学习一门新语言的痛苦越来越大。
-
@Dima 在没有明确指定类型的情况下似乎没有强制执行边界?例如,AFunc((b: Int) => {}) 不会引发错误,但 AFunc[Int]((b: Int) => {}) 会。
-
嗯 ...是的,看起来像一个错误:/但我玩了一下它,看看它实际上有多糟糕,一个发现,我真的不知道你是什么可以 do 使用此函数:在
AFunc内部没有(良好/类型安全)调用f的方法(您无法获得正确类型的参数),所以... -
这对我来说似乎很奇怪,但我猜这部分是因为它是一个坏主意,正如你所说的那样。我怀疑当我阅读更多类型级别的文档时,我会遇到一种标准的方式来做我想做的事。