【问题标题】:Scala: two implicit argument with the same declarationScala:具有相同声明的两个隐式参数
【发布时间】:2011-10-31 18:18:29
【问题描述】:

我有以下课程:

class Example(implicit doSomething1: (Double, Double) => Double, implicit doSomething2: (Double, Double) => Double)
{
  //..
}

如您所见,构造函数有两个具有相同声明的隐式参数(函数)。但我想“注入”两个不同的定义。这可能以一种隐含的方式吗?还是只有以已知的显式方式才有可能?

谢谢

【问题讨论】:

    标签: scala arguments implicit


    【解决方案1】:

    如果编译器在隐式范围内寻找implicit (Double, Double) => Double,要么恰好有一个具有更高优先级,并且两次都会选择那个,要么没有(在隐式范围内根本没有,或者更多比具有最高优先级的),并且由于缺少隐式值而出错。

    如果要区分,可能有两种不同的类型,都扩展了 Function2[Double, Double, Double]。比如

    trait Addition extends Function[Double, Double, Double]
    trait Multiplication extends Function[Double, Double, Double]
    class Example(implicit addition: Addition, implicit multiplication: Multiplication) 
    

    这可能没问题,独立选择这两个操作是有意义的。如果这两个选择需要保持一致,那么两种操作都只有一个特征可能更有意义

    trait Ring {
      def add(x: Double, y: Double): Double
      def mult(x: Double, y: Double): Double
    }
    // or `case class Ring(
    //       addition: (Double, Double) => Double, 
    //       multiplication: (Double, Double) => Double)
    class Example(implicit ring: Ring)
    

    最后,只有当您“自然地”在隐式范围内获得正确的操作时,所有这些才有用。如果您必须在每次创建示例时都将它们设为隐式,例如在

    implicit val addition = ...
    implicit val multiplication = 
    new Example
    

    你也可以是明确的。

    另外,如果预计大多数调用都使用相同的值,而您只想更改其中的一些,您可能更愿意使用默认值的参数

    class Example(doSomething1 : (Double, Double) => Double = <default value>, doSomething2  ...)
    

    你甚至可以同时拥有它,一个带有默认值的隐式参数。如果这样做,则在未找到隐式时使用默认值。

    【讨论】:

      【解决方案2】:

      class Example(implicit doSomething1: (Double, Double) => Double, doSomething2: (Double, Double) => Double)
      {
        //..
      }
      

      但是如果两个隐式参数具有相同的类型,它们显然将具有相同的值(您仍然可以显式传递不同的参数)。

      【讨论】:

        猜你喜欢
        • 2016-07-08
        • 1970-01-01
        • 1970-01-01
        • 2018-09-15
        • 2014-01-06
        • 1970-01-01
        • 1970-01-01
        • 2021-12-10
        • 2023-03-17
        相关资源
        最近更新 更多