我不明白如何正确地在Scala中应用泛型类型。我设法实现了自己的控制结构(“除非”,“ForEach”),但目前它们仅限于“Int”类型......有谁知道如何更改适用于泛型类型的实现?!
实现对我来说无关紧要,但我真的想保持现在的控制结构:
import Controls._
val Cond = false
val Elements = List(1,2,3)
Unless(Cond) {
var sum = 0
ForEach {
sum += Element
} In(Elements)
println("The Sum: " + sum)
}
我试了好几个小时,但我不知道类型参数问题的解决方案。这是我的“Int”有限实现:
object Controls {
def Unless(cond: => Boolean)(block: => Unit) = {
if(!cond) block
}
var current = 0
def ForEach(block: => Unit) = {
new {
def In(list:List[Int]) = {
list foreach { i =>
current = i
block
}
}
}
}
def Element = current
}
任何提示都非常受欢迎,因为我现在真的被困住了......
答案 0 :(得分:4)
基本上,您希望在Unless
块参数中注入一个定义:
Unless
(Cond)
{ // you want Element available here
var sum = 0
ForEach {
sum += Element
} In(Elements)
println("The Sum: " + sum)
}
您不能在外面定义它,因为它会提前修复类型。所以我会给你两个解决方案。首先,将某些内容注入块中的传统方法是将其作为参数传递:
Unless(Cond) {
var sum = 0
ForEach { Element =>
sum += Element
} In(Elements)
println("The Sum: " + sum)
}
您将无法获得单独使用的代码,因为编译器无法推断出Element
的类型。因此,需要进行以下两种更改:
ForEach[int] { Element =>
ForEach { Element: Int =>
该代码如下所示:
object Controls {
def Unless(cond: => Boolean)(block: => Unit) = {
if(!cond) block
}
def ForEach[T](block: T => Unit) = {
new {
def In(list:List[T]) = {
list foreach block
}
}
}
}
另一个解决方案是创建一个特定于类型的控件的工厂,如下所示:
object Controls {
def apply[T] = new Controls[T]
class Controls[T] {
def Unless(cond: => Boolean)(block: => Unit) = {
if(!cond) block
}
private var current: T = _
def Element = current
def ForEach(block: => Unit) = {
new {
def In(list:List[T]) = {
list foreach { i =>
current = i
block
}
}
}
}
}
}
然后你就这样使用它:
val controls = Controls[Int]; import controls._
其余的就像你的例子一样。
答案 1 :(得分:1)
def ForEach[T](block: => Unit): T = {
var current: T = _
new {
def In(list: List[T]) = {
list foreach { i =>
current = i
block
}
}
}
current
}
应该做的伎俩。
编辑:当您在ForEach方法之后使用current
时,您可能希望更改ForEach以返回current
。我编辑了代码段以反映这一点。