使用名称参数转换为元组
Conversion to tuple with by-name parameter
我想创建一个具有以下签名的函数:
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
是按名称传递的?
您可以将 call-by-name 参数更改为 thunk。
def myFunction[T](functionWithName: (String,() => T)): T = functionWithName._2()
myFunction(("abc", () => 4 * 3)) // 12
或者要让它与 implicit
一起工作,您只需要明确地提供类型 myFunction
:
myFunction[Int]("abc" -> 4 * 3) // 12
我有两个实施方案:
为整个元组命名:functionWithName: => (String, T)
自己制作class:
class MyTuple[A, B](a: A, b: => B) {
def _1: A = a
def _2: B = b
def toTuple = a -> b // optional
}
并且在某处有一个自定义的隐式方法,比如 ->
for Tuple2
(参见 Predef
中的 ArrowAssoc
):
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
在您调用 t._2
之前,不应计算 b
参数
甚至进行 toTuple
隐式转换,因此当 Tuple2
被尊重时,您可以传递 MyTuple
...
我想创建一个具有以下签名的函数:
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
是按名称传递的?
您可以将 call-by-name 参数更改为 thunk。
def myFunction[T](functionWithName: (String,() => T)): T = functionWithName._2()
myFunction(("abc", () => 4 * 3)) // 12
或者要让它与 implicit
一起工作,您只需要明确地提供类型 myFunction
:
myFunction[Int]("abc" -> 4 * 3) // 12
我有两个实施方案:
为整个元组命名:
functionWithName: => (String, T)
自己制作class:
class MyTuple[A, B](a: A, b: => B) { def _1: A = a def _2: B = b def toTuple = a -> b // optional }
并且在某处有一个自定义的隐式方法,比如 ->
for Tuple2
(参见 Predef
中的 ArrowAssoc
):
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
在您调用 t._2
之前,不应计算 b
参数
甚至进行 toTuple
隐式转换,因此当 Tuple2
被尊重时,您可以传递 MyTuple
...