2017-08-24 71 views
0

我要做到这一点,参数是懒惰的,可重复的:斯卡拉的名字重复参数

def f(actions: (=> Try[String])*) = { 
    actions.map{x => 
    if(x.isFailure) throw new Exception() 
    ... 
    } 
} 

所以,我可以用这个评估参数:

f(Try("a"), Try("b"), Try[String](new Exception()), Try({print("something"); "d"})) 

打印(“东西” )永远不会被执行,因为参数是懒惰的。

而不是:

def f(actions: (() => Try[String])*) = ??? 
f(() => Try("a"),() => Try("b"),() => Try[String](new Exception()),() => Try({print("something"); "d"})) 

它只是书写感觉无聊。
斯卡拉是否支持第一个?

回答

3

裹按名称参数,像这样:

implicit class ByNameWrapper[+A](a: => A) { def get: A = a } 

,并定义方法

def f(actions: ByNameWrapper[Try[String]]*) { 
    ... 
} 

用法是一样的正常用名字参数:

f(Try { throw new Exception }, Try { println("a"); "b" }) 
+0

也许是目前唯一的解决方案。但我认为如果语言支持它可能会更好。 – LoranceChen

1

这是要来点。或者它已经在dotty。

https://github.com/lampepfl/dotty/issues/499

+1

我认为这是'=> A *'的错误。它被解释为'Function0 [Seq [A]]'(使用方法中的参数一次评估*所有参数)。 OP希望'Seq [Function0 [A]]',其中每个参数都是单独评估的。 – HTNW

+0

@HTNW tl;博士我猜。语义不在scala中。 –

+0

对不起''(=> T)*',它只是一个'lazy val x:Seq [T]'。我实际上需要一个'val x:Stream [T]'。 – LoranceChen