Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala传递隐式转换 我有3个Scala类(A、B、C) 我有一个隐式转换从A->B和一个从B->C_Scala_Implicit Conversion - Fatal编程技术网

Scala传递隐式转换 我有3个Scala类(A、B、C) 我有一个隐式转换从A->B和一个从B->C

Scala传递隐式转换 我有3个Scala类(A、B、C) 我有一个隐式转换从A->B和一个从B->C,scala,implicit-conversion,Scala,Implicit Conversion,在我的代码中的某个时刻,我想对a调用一个C方法。这可能吗? 我提出的一个解决方案是从a->C进行转换,但这似乎有些多余 注: 当我在A上调用B方法时,它就工作了 当我在B上调用C方法时,它是有效的 当我在A上调用C方法时,它说在A的主体中找不到该方法 谢谢…你写问题的时候好像打错了。您的意思是说您有来自A->B和B->C的隐式转换,并且您发现A->C转换是多余的吗 Scala有一条规则,它在必要时只会应用一个隐式转换(而不是两个),因此您不能指望Scala神奇地组合a->B和B->C,以进行

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

注:

  • 当我在A上调用B方法时,它就工作了
  • 当我在B上调用C方法时,它是有效的
  • 当我在A上调用C方法时,它说在A的主体中找不到该方法

谢谢…

你写问题的时候好像打错了。您的意思是说您有来自
A->B
B->C
的隐式转换,并且您发现
A->C
转换是多余的吗


Scala有一条规则,它在必要时只会应用一个隐式转换(而不是两个),因此您不能指望Scala神奇地组合
a->B
B->C
,以进行所需的转换。您需要提供自己的
A->C
转换。它不是多余的。

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


但是,如果指定要进行隐式转换,则可以让Scala链为您进行隐式转换。关键是将泛型与
提示一起使用:这看起来更像是传递性而不是关联性。你也不是第一个想让Scala这么做的人。另外,
A->C
可能是您第二行中的
B->C
的一个输入错误?请看一下:出现这种情况的一个原因是中间类型可能有多种可能性。如果存在隐式转换
A->B1
B1->C
A->B2
B2->C
,编译器将无法猜出您想要哪一个。感谢您的快速响应。使用
隐式定义传递[A,B,C](隐式a2b:A=>B,b2c:B=>C):A=>C=(A:A:A=>b2c(a2b(A))
理论上可以进行传递解析。但在这种情况下,每个
隐式[A=>B]
都会发散,因为存在隐式
$confirms[A]:A=>A
-解析算法最终会循环。感谢您的快速响应。是的,我尝试了单元编译器错误。所以我又回到了手动弥合差距。谢谢你的帮助。
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