使用简单类型的隐式值有什么方便的方法?理想情况下,我想做这样的事情:
scala> :paste
// Entering paste mode (ctrl-D to finish)
type A = String
type B = String
implicit val a: A = "a"
implicit val b: B = "b"
def c(implicit ab: A) = println(ab)
// Exiting paste mode, now interpreting.
defined type alias A
defined type alias B
a: A = a
b: B = b
c: (implicit ab: A)Unit
scala> c
<console>:13: error: ambiguous implicit values:
both value a in object $iw of type => A
and value b in object $iw of type => B
match expected type A
不能将最终案例类(如String或Long)子类化为
scala> class C extends String
<console>:11: error: illegal inheritance from final class String
class C extends String
答案 0 :(得分:3)
虽然Tim是正确的,但他的方法会在字符串周围创建一个包装器,从而引入运行时开销。我们可以让编译器完成所有这些操作,而无需使用称为类型标记的技术创建新对象。以下代码是从shapeless来源无耻地获取的:
trait Tagged[U]
type @@[+T, U] = T with Tagged[U]
class Tagger[U] {
def apply[T](t : T) : T @@ U = t.asInstanceOf[T @@ U]
}
def tag[U] = new Tagger[U]
使用这些定义,您可以编写以下内容:
trait A
trait B
implicit def a: String @@ A = tag[A]("foo")
implicit def b: String @@ B = tag[B]("bar")
def foo(implicit a: String @@ A) = a.toString
def bar(implicit b: String @@ B) = b.toString
scala> foo
res21: String = foo
scala> bar
res22: String = bar
答案 1 :(得分:2)
使用“type”时,您要为类型定义别名,而不是实际的新类型。
您要做的是定义一个实际的新类型。
case class A(a: String)
case class B(b: String)
implicit val a = A("a")
implicit val b = B("b")
def c(implicit ab: A) = println(ab.a)