使用by-name参数转换为元组

时间:2017-10-18 15:56:56

标签: scala implicit-conversion callbyname

我想创建一个具有以下签名的函数:

def myFunction[T](functionWithName: (String, => T)): T 

所以我可以打电话给它,例如:val x = myFunction("abc" -> 4 * 3)。但是,元组不接受按名称参数,因此上面的签名无效。

this answer的启发,我尝试了以下隐式转换:

implicit class ByName[T](getValue: => T) extends Proxy {
  def apply(): T = getValue
  def self = apply()
}

def myFunction[T](functionWithName: (String, ByName[T])): T = {
  // do something
  functionWithName._2()
}

然而,在这种情况下隐含的不起作用(与链接的答案不同)。

  • 为什么隐含转换为ByName不起作用?
  • 如何通过名称传递myFunction("abc" -> 4 * 3)来调用4 * 3达到预期效果?

2 个答案:

答案 0 :(得分:4)

您可以将call-by-name参数更改为thunk。

for cur IN c_trd( <value_for_pi_bps_batch_seq>)
LOOP
   DBMS_OUTPUT.PUT_LINE(cur.bps_batch_seq , cur.hetid,....); 
END LOOP;

或要让它与def myFunction[T](functionWithName: (String,() => T)): T = functionWithName._2() myFunction(("abc", () => 4 * 3)) // 12 一起使用,您只需要明确地向implicit提供类型:

myFunction

答案 1 :(得分:1)

我有两个提案要实现这个:

  • 按名称制作整个元组:functionWithName: => (String, T)

  • 创建自己的课程:

    class MyTuple[A, B](a: A, b: => B) {
      def _1: A = a
      def _2: B = b
      def toTuple = a -> b // optional
    }
    

并在某处设置自定义隐式方法,例如->的{​​{1}}(请参阅Tuple2中的ArrowAssoc):

Predef

然后你可以这样说:

  implicit final class ArrAssoc[A](private val self: A) extends AnyVal {
    @inline def -->[B](y: => B): MyTuple[A, B] = {
      new MyTuple(self, y)
    }
  }

在致电 val t = 1 --> { println("blah"); 5 } //t._2 //t.toTuple 之前,不应评估b参数 或者甚至进行t._2次转换,因此当尊重toTuple时,您可以传递Tuple2 ...