2014-07-07 23 views
6

突破是好的,但過於冗長:替代的突破是更簡潔

List(1, 2, 3).map{i => (i * 2, i/2.0, i.toString)}(breakOut) : Array[(Int, Double, String)] 

我不想指定元素類型。我想是這樣的:

List(1, 2, 3).map{i => (i * 2, i/2.0, i.toString)}(build[Array]) 

我可以隨便寫一個buildArray,但後來我需要一個buildSet,buildList,等等。所以我想要的東西一般。

加分(;-)),如果你可以把它的地圖工作(使用相同的名稱build,不BUILD2或buildMap)

+1

[這是](http://pastebin.com/rsmFtqdt)不是你想要的,但我想這是你能得到的最好的。這對'String'或'Map'不起作用。 – senia

+0

是的,這是我想要的。我做了同樣的事情,但得到了混合的通用參數(在def中使用T,在代碼中使用A)並且無法從編譯器錯誤中找出它。 – IttayD

+1

@senia也許答案是? –

回答

4

這不會對StringMap工作。此代碼還需要scala.language.higherKinds

import collection.generic.CanBuildFrom 
import collection.breakOut 

class Build[To[_]] 

def build[To[_]] = new Build[To] 

implicit def buildToCbf[From, T, To[_]](b: Build[To]) 
             (implicit cbf: CanBuildFrom[Nothing,T,To[T]]): CanBuildFrom[From,T,To[T]] = 
    collection.breakOut 

List(1, 2, 3).map{i => (i * 2, i/2.0, i.toString)}(build[Array]) 
//res0: Array[(Int, Double, String)] = Array((2,0.5,1), (4,1.0,2), (6,1.5,3)) 
1

Senia的解決方案非常棒。不幸的是,他提到這不適用於MapString。 這裏是另一種選擇(根據他的解決方案),這不:

import collection.generic.CanBuildFrom 
import collection.breakOut 

class Build[To] 

def build[TargetSuperType] = new Build[TargetSuperType] 

implicit def buildToCbf[From, T, TargetSuperType, To<:TargetSuperType](b: Build[TargetSuperType]) 
             (implicit cbf: CanBuildFrom[Nothing,T,To]): CanBuildFrom[From,T,To] = 
    collection.breakOut 

List(1, 2, 3).map{i => (i * 2, i/2.0, i.toString)}(build[Array[_]]) 
//res0: Array[(Int, Double, String)] = Array((2,0.5,1), (4,1.0,2), (6,1.5,3)) 

List(1, 2, 3).map{i => (i * 2, i.toString)}(build[Map[_,_]]) 
//res1: scala.collection.immutable.Map[Int,String] = Map(2 -> 1, 4 -> 2, 6 -> 3) 

List('a', 'b', 'c').map(_.toUpper)(build[String]) 
//res2: String = ABC 

這一點更詳細的,因爲現在你不只是做build[Array],但build[Array[_]]。作爲交換,您可以指定所需的任何目標集合,而不考慮類型參數的數量(例如MapString)。

另外,您還可以完全明確的(同樣使用breakOut時)如果你選擇:

scala> List(1, 2, 3).map{i => (i * 2, i/2.0, i.toString)}(build[Array[(Int, Double, String)]]) 
res3: Array[(Int, Double, String)] = Array((2,0.5,1), (4,1.0,2), (6,1.5,3)) 

所有具有相同的語法(換句話說,使用相同的名稱build,爲你的要求)