问题 方法采用Seq [T]返回String而不是Seq [Char]


我想实现任意的方法 Seq[T] 并返回 Seq[T] 同样。但当 String 提供它也应该返回 String

通过 String 由于某些隐式转换而起作用 String 至 WrappedString extends IndexedSeq[Char],但我明白了 Seq[Char] 作为回报。有可能得到 String 背部?

val sx: Seq[Int] = firstAndLast(List(1, 2, 3, 4))
val s1: Seq[Char] = firstAndLast("Foo Bar")
val s2: String = firstAndLast("Foo Bar")  //incompatible types error

def firstAndLast[T](seq: Seq[T]) = Seq(seq.head, seq.last)

firstAndLast() 实现是无关紧要的,这只是一个例子。


3815
2018-05-21 16:42


起源



答案:


对的,这是可能的。你必须要求其中一个 CanBuildFromS:

import scala.collection.generic.CanBuildFrom

def firstAndLast[CC, A, That](seq: CC)(implicit asSeq: CC => Seq[A], cbf: CanBuildFrom[CC, A, That]): That = {
  val b = cbf(seq)
  b.sizeHint(2)
  b += seq.head
  b += seq.last
  b.result
}

这也适用于数组。额外奖励:示例中的所有行都将按预期编译和工作。


15
2018-05-21 16:59



我很确定它不适用于Arrays;你没有定义清单 - oxbow_lakes
它确实有效,因为需要 ClassManifest 隐含地提供给提供适当的方法 CanBuildFrom, scala.Array.canBuildFrom。 - Jean-Philippe Pellet
迈尔斯的这应该会更容易 FromRepr, 我猜。 - Daniel C. Sobral
@ DanielC.Sobral听起来很有趣;一个例子怎么样? - Jean-Philippe Pellet
@ Jean-Philippe,感谢您的回答和后续评论。我被激怒试图找到asSeq的含义来自何处,并发现了以下内容 命令 IntelliJ上的Ctrl + Shift + P,它显示呼叫站点的实际隐式参数。 - Don Mackenzie


答案:


对的,这是可能的。你必须要求其中一个 CanBuildFromS:

import scala.collection.generic.CanBuildFrom

def firstAndLast[CC, A, That](seq: CC)(implicit asSeq: CC => Seq[A], cbf: CanBuildFrom[CC, A, That]): That = {
  val b = cbf(seq)
  b.sizeHint(2)
  b += seq.head
  b += seq.last
  b.result
}

这也适用于数组。额外奖励:示例中的所有行都将按预期编译和工作。


15
2018-05-21 16:59



我很确定它不适用于Arrays;你没有定义清单 - oxbow_lakes
它确实有效,因为需要 ClassManifest 隐含地提供给提供适当的方法 CanBuildFrom, scala.Array.canBuildFrom。 - Jean-Philippe Pellet
迈尔斯的这应该会更容易 FromRepr, 我猜。 - Daniel C. Sobral
@ DanielC.Sobral听起来很有趣;一个例子怎么样? - Jean-Philippe Pellet
@ Jean-Philippe,感谢您的回答和后续评论。我被激怒试图找到asSeq的含义来自何处,并发现了以下内容 命令 IntelliJ上的Ctrl + Shift + P,它显示呼叫站点的实际隐式参数。 - Don Mackenzie