通常采用类型并返回相同类型的函数 [英] Function which generically takes a type and returns the same type

查看:137
本文介绍了通常采用类型并返回相同类型的函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我很难理解为什么Scala编译器不满意这个函数定义:

  def trimNonWordCharacters [T< ;:Iterable [String]](items:T):T = 
items map {_.replaceAll(\\W,)}
/ pre>

以下是 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 on Iterable returns an Iterable, so even if T is a subclass of Iterable, it's map method will return Iterable.

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 another T. For example, mapping a BitSet into a String cannot result in a BitSet. So we need something else: something that teaches how to build a T from a T, where the mapped elements are of type String. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆