我有一个函数,需要相同类型的可变数量的参数,这听起来像varargs的教科书用例:
def myFunc[A](as: A*) = ???
Run Code Online (Sandbox Code Playgroud)
我遇到的问题是myFunc无法接受空参数列表.在运行时有一种简单的方法可以强制执行:
def myFunc[A](as: A*) = {
require(as.nonEmpty)
???
}
Run Code Online (Sandbox Code Playgroud)
问题在于它发生在运行时,而不是编译时.我希望编译器拒绝myFunc().
一种可能的解决方案是:
def myFunc[A](head: A, tail: A*) = ???
Run Code Online (Sandbox Code Playgroud)
这在myFunc使用内联参数调用时有效,但我希望我的库的用户能够传入一个List[A],这种语法非常笨拙.
我可以尝试两者兼得:
def myFunc[A](head: A, tail: A*) = myFunc(head +: tail)
def myFunc[A](as: A*) = ???
Run Code Online (Sandbox Code Playgroud)
但是我们回到了我们开始的地方:现在有一种myFunc使用空参数列表调用的方法.
我知道scalaz NonEmptyList,但是尽可能地,我想继续使用stlib类型.
有没有办法通过标准库来实现我的想法,或者我是否需要接受一些运行时错误处理,以获得真正感觉编译器应该能够处理的内容?
这样的事情怎么样?
scala> :paste
// Entering paste mode (ctrl-D to finish)
def myFunc()(implicit ev: Nothing) = ???
def myFunc[A](as: A*) = println(as)
// Exiting paste mode, now interpreting.
myFunc: ()(implicit ev: Nothing)Nothing <and> [A](as: A*)Unit
myFunc: ()(implicit ev: Nothing)Nothing <and> [A](as: A*)Unit
scala> myFunc(3)
WrappedArray(3)
scala> myFunc(List(3): _*)
List(3)
scala> myFunc()
<console>:13: error: could not find implicit value for parameter ev: Nothing
myFunc()
^
scala>
Run Code Online (Sandbox Code Playgroud)
用具有适当implicitNotFound注释的类替换Nothing 应该允许合理的错误消息.
使用scala.collection.immutable.::
::是列表的缺点
在标准库中定义
::[A](head: A, tail: List[A])
Run Code Online (Sandbox Code Playgroud)
用于::定义myFunc
def myFunc[A](list: ::[A]): Int = 1
def myFunc[A](head: A, tail: A*): Int = myFunc(::(head, tail.toList))
Run Code Online (Sandbox Code Playgroud)
Scala REPL
scala> def myFunc[A](list: ::[A]): Int = 1
myFunc: [A](list: scala.collection.immutable.::[A])Int
scala> def myFunc[A](head: A, tail: A*): Int = myFunc(::(head, tail.toList))
myFunc: [A](head: A, tail: A*)Int
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
423 次 |
| 最近记录: |