安全地链接隐式转换 [英] Safely chaining implicit conversions

查看:83
本文介绍了安全地链接隐式转换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您可以执行此操作以将隐式转换转换为链:

You can do this to get implicit conversions to chain:

package language

object chainedImplicits {
  implicit def chainImplicits[A, B, C](a: A)(implicit conv1: A => B, conv2: B => C): C = conv2(conv1(a))
}

但这显然不安全.

尽管如此,我看不到任何问题

I can't see anything wrong with this version, though:

package language

package chainedImplicits {

  final class Chained[A, B] private[chainedImplicits] (val f: A => B)

  trait Low { this: `package`.type =>
    implicit def startChaining(implicit conv: A => B): Chained[A, B] = new Chained[A, B](conv)
    implicit def chainImplicits[A, B, C](implicit conv1: Chained[A, B], conv2: B => C): Chained[B, C] = new Chained(conv1.f andThen conv2)
  }

}

package object chainedImplicits extends Low {
  implicit def endChain[A, B](a: A)(implicit conv: Chained[A, B]): B = conv.f(a)
}

这里有鱼吗?

推荐答案

首先,我无法让您的第一个显然不安全"的示例执行任何操作:

First, I can't get your first "obviously not safe" example to do anything:

import language.implicitConversions

object Test {
  implicit def chain[A, B, C](a: A)(implicit ab: A => B, bc: B => C): C = bc(ab(a))

  case class X()
  case class Y()
  case class Z()

  implicit def xy(x: X) = Y()
  implicit def yz(y: Y) = Z()

  val z: Z = X()
}

...

type mismatch;
  found   : Test.X
  required: Test.Z
   val z: Z = X()
               ^

接下来,第二个示例中明显的"catch"是它没有编译.您是否真的尝试过?无论如何,在修复"它之后,它仍然无法执行您想要的操作:

Next, the obvious "catch" in your second example is that it doesn't compile. Did you actually try it? Regardless, after "fixing" it, it still doesn't do what you want:

import language.implicitConversions

class Convert[A, B](val convert: A => B) extends AnyVal
trait Convert0 {
  implicit def convert[A, B](implicit ab: A => B): Convert[A, B] = new Convert(ab)
  implicit def convert[A, B, C](implicit ab: Convert[A, B], bc: B => C): Convert[A, C] = new Convert(ab.convert andThen bc)
}
object Convert extends Convert0 {
  implicit def convert[A, B](a: A)(implicit convert: Convert[A, B]): B = convert.convert(a)
}

object Test {
  case class X()
  case class Y()
  case class Z()

  implicit def xy(x: X) = Y()
  implicit def yz(y: Y) = Z()

  val z: Z = X()
}

这给出了相同类型的不匹配错误.据我所知,如果要隐式转换链接起来,则必须对其进行明确说明:

This gives the same type mismatch error. To my knowledge, if you want implicit conversions to chain, you have to be explicit about it:

import language.implicitConversions

object test {
  case class X()
  case class Y()
  case class Z()

  // anything convertible to X is convertible to Y
  implicit def xy[A <% X](x: A) = Y()

  // anything convertible to Y is convertible to Z
  implicit def yz[B <% Y](y: B) = Z()

  val z: Z = X()
}

这篇关于安全地链接隐式转换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆