如何在以下示例中的map
特征中使用Iterable
方法?
据我所知,这个方法将返回一个我必须调用以执行内部逻辑的函数。
trait Container[E] {
def += (e: E): Unit
}
trait Iterable[E, C[X] <: Container[X]]
{
def iterator(): Iterator[E]
def build[F](): C[F]
def map[F](f : (E) => F) : C[F] = {
val res = build[F]()
val iter = iterator()
while (iter.hasNext) res += f(iter.next())
res
}
}
class Buffer[T] extends Container[T]
{
val list = scala.collection.mutable.ListBuffer.empty[T]
def Children = list
def += (e: T): Unit = list += e
}
class Range(val low: Int, val high: Int) extends Iterable[Int, Buffer] {
def iterator() = new Iterator[Int]
{
private var i = low
def hasNext = i <= high
def next() = { i += 1; i - 1 }
}
def build[F]() = new Buffer[F]
}
val range = new Range(1, 3)
var list = range.map[String](_)
答案 0 :(得分:1)
new Range(2,5).map(_.toString)
答案 1 :(得分:1)
该方法具有以下特征:
trait Iterable[E, C[X] <: Container[X]] {
def map[F](f : (E) => F) : C[F]
// ...
}
首先,让我们看一下f
参数的类型。签名(E) => F
表示f
是一个函数,它接受类型E
的单个参数并返回类型F
的值。具有此签名的任何函数(或方法)都可以作为参数传递给map()
。另请参阅Scala documentation。
要理解的另一个重要事项是map
函数是通用的类型参数F
。此类型参数的值可以手动指定,也可以由编译器从传递给map的参数中推断出来:
new Range(1,2).map[String](_.toString) // F is String
// new Range(1,2).map[Int](_.toString) // F is Int, compilation will fail
val mapFunction: Int => String = _.toString
new Range(1,2).map(mapFunction) // mapFunction is a function from Int to String,
// the compiler infers F is String
基本上,例如使用Range
,您可以向map()
函数传递任何带有Int
参数的函数(因为Range
将E
绑定到Int
)并返回任何内容(Unit
除外)。还有一些例子:
val r = Range(1,2)
val v1: Buffer[String] = r.map(_.toString)
val v2: Buffer[Int] = r.map(i => i + 1)
val v3: Buffer[Double] = r.map(Int.int2double)
val i: Int = 1
val v4: Buffer[Int] = r.map(i.max)
正如您所看到的,map()
会返回Buffer[F]
类型,因为Range
绑定到C[X]
类型参数。
正如@vitalii指出的那样,这个问题与高等级的类型无关。有关这些内容的详细信息,请查看other questions或blogs。