[英]Scala implicits and type aliases
假设我有以下代码:
object Potato extends App {
type CoolString = String
type AwesomeString = String
def potato(string: String)(implicit coolString: CoolString, awesomeString: AwesomeString) = {
s"$string is a string. Oh, but don't forget - $coolString and also $awesomeString"
}
implicit val ice : CoolString = "Really Cold Ice"
implicit val awe : AwesomeString = "Awe inspiring object"
potato("Stringerino")
}
此代码失败并出现问题
[error] ... ambiguous implicit values:
[error] both value ice in object Potato of type => Potato.CoolString
[error] and value awe in object Potato of type => Potato.AwesomeString
[error] match expected type Potato.CoolString
[error] potato("Stringerino")
这样隐式的使用是不可能的吗?
这样隐式的使用是不可能的吗?
不仅不可能,而且依赖于将String
这样的常规类型作为隐式接受这种方法也是危险的。 考虑一下,范围内的任何String
实例都将是合格的候选者,可以被传递到方法中!
类型别名就是类型别名,仅此而已。 对于编译器, CoolString
和AwesomeString
都只是String
。
更好的方法是利用标记类型。 例如,这是使用shapeless的标记类型 :
import shapeless.tag.@@
trait CoolString
trait AwesomeString
type ReallyCoolString = String @@ CoolString
type ReallyAwesomeString = String @@ AwesomeString
接着:
import shapeless.tag
def potato(string: String)(implicit coolString: ReallyCoolString, awesomeString: ReallyAwesomeString) = {
s"$string is a string. Oh, but don't forget - $coolString and also $awesomeString"
}
def main(args: Array[String]): Unit = {
implicit val ice = tag[CoolString][String]("Really Cold Ice")
implicit val awe = tag[AwesomeString][String]("Awe inspiring object")
println(potato("Stringerino"))
}
产量:
Stringerino is a string.
Oh, but don't forget - Really Cold Ice and also Awe inspiring object
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.