通常采用类型并返回相同类型的函数 [英] Function which generically takes a type and returns the same type
问题描述
我很难理解为什么Scala编译器不满意这个函数定义:
def trimNonWordCharacters [T< ;:Iterable [String]](items:T):T =
/ pre>
items map {_.replaceAll(\\W,)}
以下是 REPL 输出:
scala> def trimNonWordCharacters [T <:Iterable [String]](items:T):T =
items map {_.replaceAll(\\W,)}
< console> ;:5:错误:类型不匹配;
found:Iterable [java.lang.String]
必需:T
def trimNonWordCharacters [T <:Iterable [String]](items:T):T = items map {_。 replaceAll(\\W,)}
目标是传入任何实现一个Iterable并得到相同类型的退出。这是可能吗?
解决方案
映射 c> Iterable
返回Iterable
,因此即使T
是Iterable
,它的映射
方法将返回Iterable
。
要更好的输入,你必须这样写:
import items.collection.IterableLike
def trimNonWordCharacters [T <:Iterable [String]](items:T with IterableLike [String,T]):T =
items map {_.replaceAll( \\\W,)}
但是,这也不行,因为没有让
T
上的映射生成另一个T
的信息。例如,将BitSet
映射到String
中不能产生BitSet
。所以我们需要别的东西:教会如何从T
构建T
,其中映射的元素是键入String
。像这样:import scala.collection.IterableLike
import scala.collection.generic.CanBuildFrom
def trimNonWordCharacters [T <:Iterable [String]]
(items:T with IterableLike [String,T])
(隐含cbf:CanBuildFrom [T,String,T]):T =
items map {_.replaceAll(\\W,)}
I am having a tough time understanding why the Scala compiler is unhappy about this function definition:
def trimNonWordCharacters[T <: Iterable[String]](items: T): T = items map { _.replaceAll("\\W", "") }
Here is the REPL output:
scala> def trimNonWordCharacters[T <: Iterable[String]](items: T): T = items map { _.replaceAll("\\W", "") } <console>:5: error: type mismatch; found : Iterable[java.lang.String] required: T def trimNonWordCharacters[T <: Iterable[String]](items: T): T = items map { _.replaceAll("\\W", "") }
The goal is to pass in any implementation of an Iterable and get the same type of back out. Is this possible?
解决方案The
map
method onIterable
returns anIterable
, so even ifT
is a subclass ofIterable
, it'smap
method will returnIterable
.To get better typing, you'd have to write it like this:
import scala.collection.IterableLike def trimNonWordCharacters[T <: Iterable[String]](items: T with IterableLike[String, T]): T = items map { _.replaceAll("\\W", "") }
However, that won't work either, because there's no information that let a map on
T
to generate anotherT
. For example, mapping aBitSet
into aString
cannot result in aBitSet
. So we need something else: something that teaches how to build aT
from aT
, where the mapped elements are of typeString
. Like this:import scala.collection.IterableLike import scala.collection.generic.CanBuildFrom def trimNonWordCharacters[T <: Iterable[String]] (items: T with IterableLike[String, T]) (implicit cbf: CanBuildFrom[T, String, T]): T = items map { _.replaceAll("\\W", "") }
这篇关于通常采用类型并返回相同类型的函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!