按名称重复参数
Posted
技术标签:
【中文标题】按名称重复参数【英文标题】:By-name repeated parameters 【发布时间】:2011-02-12 00:37:36 【问题描述】:如何在 Scala 中传递按名称重复的参数?
以下代码无法运行:
scala> def foo(s: (=> String)*) =
<console>:1: error: no by-name parameter type allowed here
def foo(s: (=> String)*) =
^
还有其他方法可以将可变数量的按名称参数传递给方法吗?
【问题讨论】:
重复:***.com/questions/2618891/… 在这种情况下您要使用按名称参数的原因是什么?也许我们可以提出更好的解决方案。 【参考方案1】:目前不支持重复的按名称参数。
【讨论】:
【参考方案2】:这不是很漂亮,但它允许您通过 varargs 样式传递 byname 参数
def printAndReturn(s: String) =
println(s)
s
def foo(s: (Unit => String)*)
println("\nIn foo")
s foreach _() // Or whatever you want ...
foo()
foo((Unit) => printAndReturn("f1"),
(Unit) => printAndReturn("f2"))
这会产生
在 foo 中
在富 f1 f2
【讨论】:
看和写肯定不愉快。我继续鼓励人们区分名称参数(使用 thunk 实现,但在逻辑上不同)和用作参数的函数值。方法和函数也是如此。 我认为 Randall 的 cmets 是公平的,以上内容可以通过辅助函数来包装/预处理参数进行改进,例如: def deferred(block: => String) = () = > 带有 foo 的块更改为: def foo(s: (() => String)*) 给予,例如: foo(deferred val a = "apples"; "Green "+apples, deferred "Pears" )【参考方案3】:如果为漂亮的语法而苦苦挣扎,则可以使用隐式来实现目标。
implicit def arg2func(arg: ⇒ Byname): (() => Byname) = () ⇒ arg
def foo(params: (() ⇒ Byname)*): Unit =
println("foo: not yet evaluated.")
params.foreach(_())
def boo(params: Byname*): Unit =
println("boo: already evaluated")
foo(Byname(0), Byname(1), Byname(2))
println()
boo(Byname(3), Byname(4), Byname(5))
case class Byname(n: Int)
println(n)
打印出来的:
foo:尚未评估。
0 1 2
3 4 5
嘘:已经评估过
【讨论】:
【参考方案4】:它适用于 Scala 3:
scala> def f(i: => Int*): Int = i.sum
def f(i: => Int*): Int
scala> f(1, 2, 3)
val res0: Int = 6
【讨论】:
【参考方案5】:你可以写() => String
而不是Unit(反正都是一样的)
【讨论】:
这真的不是“一回事”。在方法中调用和使用它们的语义和语法都不同。【参考方案6】:感谢 Randall Schulz 提供了很好的单行答案。
我一直在寻找这种可能性,以便制作一个可以同时运行多个断言的 INVARIANT 工具。然后我想出的解决方案是简单地使用 1..5 个apply
方法,因为这里需要的可变参数的数量是有限的。
object INVARIANT
def apply =
def apply( conds: => Boolean * ) = // DOES NOT COMPILE
conds.foreach( assert(_) )
object TestX extends App
class A
println("A body")
INVARIANT( true )
class B extends A
println("B body")
INVARIANT( true, false )
new B
我发布此内容是为了展示我认为在“按名称”变量上使用 varargs 的有效用例。如果有更好的名字,欢迎留言。谢谢。
【讨论】:
以上是关于按名称重复参数的主要内容,如果未能解决你的问题,请参考以下文章