繁体   English   中英

Scala隐式和类型别名

[英]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实例都将是合格的候选者,可以被传递到方法中!

类型别名就是类型别名,仅此而已。 对于编译器, CoolStringAwesomeString都只是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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM