【问题标题】:Scala transitive implicit conversionScala 传递隐式转换
【发布时间】:2012-03-04 18:30:39
【问题描述】:
  • 我有 3 个 Scala 类(A、B、C)。
  • 我有一个从 A -> B 的隐式转换和一个从 B -> C 的隐式转换。

在我的代码中,我想在 A 上调用 C 方法。这可能吗? 我想出的一个解决方法是从 A -> C 进行转换,但这似乎有些多余。

注意:

  • 当我在 A 上调用 B 方法时,它可以工作。
  • 当我在 B 上调用 C 方法时,它可以工作。
  • 当我在 A 上调用 C 方法时,它说它没有在 A 的主体中找到该方法

谢谢...

【问题讨论】:

  • 提示:这看起来更像传递性而不是关联性。而且你不是第一个想要这个 Scala 隐含的人。另外A -> C 可能是您第二行中B -> C 的错字?

标签: scala implicit-conversion


【解决方案1】:

您在写问题时似乎打错了。您的意思是说您有来自A -> BB -> C 的隐式转换,并且您发现A -> C 转换是多余的?

Scala 有一个规则,它只会在必要时应用 一个 隐式转换(但绝不是两个),所以你不能指望 Scala 神奇地组合 A -> BB -> C您需要的转换。您需要提供自己的A -> C 转换。这不是多余的。

【讨论】:

  • 出现这种情况的一个原因是中间类型可能有多种可能性。如果存在隐式转换A -> B1B1 -> CA -> B2B2 -> C,编译器将无法猜测您想要哪一个。
  • 感谢您的快速回复。
  • implicit def transitive[A, B, C](implicit a2b: A => B, b2c: B => C): A => C = (a: A) => b2c(a2b(a)) 理论上可以进行传递解析。但在这种情况下,每个implicitly[A => B] 都会发散,因为存在隐含的$conforms[A]: A => A - 解析算法最终会循环。
【解决方案2】:

这似乎有些多余,但A -> C 转换正是您应该提供的。原因是如果隐式很少见,传递链也很少见,并且可能是您想要的。但是,如果隐式很常见,那么您很可能能够将任何东西变成任何东西(或者,如果您添加一个看起来很方便的隐式,突然间各种行为都会改变,因为您为隐式转换开辟了不同的途径)。

您可以让 Scala 为您链接隐式转换,但是,如果您指定它是要完成的。关键是将泛型与<% 一起使用,这意味着“可以转换为”。这是一个例子:

class Foo(i: Int) { def foo = i }
class Bar(s: String) { def bar = s }
class Okay(b: Boolean) { def okay = b }
implicit def to_bar_through_foo[T <% Foo](t: T) = new Bar((t: Foo).foo.toString)
implicit def to_okay_through_bar[U <% Bar](u: U) = new Okay((u: Bar).bar.length < 4)

scala> (new Foo(5)).okay
res0: Boolean = true

【讨论】:

  • 感谢您的快速回复。
  • 是的,我尝试了 Unit 编译器错误中生成了一个奇怪的隐式。所以我回到手动弥合差距。坦克为您提供帮助。
猜你喜欢
  • 2018-06-03
  • 2012-04-15
  • 2018-09-16
  • 2011-09-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多