代码之家  ›  专栏  ›  技术社区  ›  Dimitris Andreou

如何在scala中使用多个输入的implicit?

  •  11
  • Dimitris Andreou  · 技术社区  · 14 年前

    例如,如何在隐式应用以下内容的情况下编写表达式:

    implicit def intsToString(x: Int, y: Int) = "test"
    
    val s: String = ... //?
    

    谢谢

    2 回复  |  直到 13 年前
        1
  •  18
  •   retronym    14 年前

    一个参数的隐式函数用于自动将值转换为预期类型。这些被称为隐式视图。有了两个论点,它既不起作用,也没有意义。

    您可以将隐式视图应用于 TupleN :

    implicit def intsToString( xy: (Int, Int)) = "test"
    val s: String = (1, 2)
    

    还可以将任何函数的最终参数列表标记为隐式。

    def intsToString(implicit x: Int, y: Int) = "test"
    implicit val i = 0
    val s: String = intsToString
    

    或者,结合这两种用法 implicit :

    implicit def intsToString(implicit x: Int, y: Int) = "test"
    implicit val i = 0
    val s: String = implicitly[String]
    

    然而,在这种情况下,它并不是真正有用的。

    更新

    为了详细阐述马丁的评论,这是可能的。

    implicit def foo(a: Int, b: Int) = 0
    // ETA expansion results in:
    // implicit val fooFunction: (Int, Int) => Int = (a, b) => foo(a, b)
    
    implicitly[(Int, Int) => Int]
    
        2
  •  4
  •   Miles Sabin    13 年前

    Jason的答案遗漏了一个非常重要的例子:一个隐式函数,它有多个参数,除了第一个参数外,其他参数都是隐式的……这需要两个参数列表,但考虑到问题的表达方式,这似乎并不超出范围。

    下面是一个隐式转换的例子,它有两个参数,

    case class Foo(s : String)
    case class Bar(i : Int)
    
    implicit val defaultBar = Bar(23)
    
    implicit def fooIsInt(f : Foo)(implicit b : Bar) = f.s.length+b.i
    

    复制会话示例,

    scala> case class Foo(s : String)
    defined class Foo
    
    scala> case class Bar(i : Int)
    defined class Bar
    
    scala> implicit val defaultBar = Bar(23)
    defaultBar: Bar = Bar(23)
    
    scala> implicit def fooIsInt(f : Foo)(implicit b : Bar) = f.s.length+b.i
    fooIsInt: (f: Foo)(implicit b: Bar)Int
    
    scala> val i : Int = Foo("wibble")
    i: Int = 29