- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
根据下面的示例,调用 xs.toList.map(_.toBuffer)
成功,但 xs.toBuffer.map(_.toBuffer)
失败。但是,当使用中间结果执行后者的步骤时,它会成功。是什么原因导致这种不一致呢?
scala> "ab-cd".split("-").toBuffer
res0: scala.collection.mutable.Buffer[String] = ArrayBuffer(ab, cd)
scala> res0.map(_.toBuffer)
res1: scala.collection.mutable.Buffer[scala.collection.mutable.Buffer[Char]] = ArrayBuffer(ArrayBuffer(a, b), ArrayBuffer(c, d))
scala> "ab-cd".split("-").toBuffer.map(_.toBuffer)
<console>:8: error: missing parameter type for expanded function ((x$1) => x$1.toBuffer)
"ab-cd".split("-").toBuffer.map(_.toBuffer)
^
scala> "ab-cd".split("-").toList.map(_.toBuffer)
res3: List[scala.collection.mutable.Buffer[Char]] = List(ArrayBuffer(a, b), ArrayBuffer(c, d))
最佳答案
查看 toBuffer
的定义和toList
:
def toBuffer[A1 >: A]: Buffer[A1]
def toList: List[A]
如您所见,toBuffer
是通用的,而 toList
不是。我相信,造成这种差异的原因是 Buffer
是不变的,而 List
是协变的。
假设我们有以下类:
class Foo
class Bar extends Foo
因为List
是协变的,可以调用toList
在 Iterable[Bar]
的实例上并将结果视为 List[Foo]
。如果List
如果不变,则情况并非如此。 Buffer
不变,如果 toBuffer
被定义为def toBuffer: Buffer[A]
您同样无法处理结果的toBuffer
(在 Iterable[Bar]
的实例上)作为 Buffer[Foo]
的实例(因为 Buffer[Bar]
不是 Buffer[Foo]
的子类型,与列表不同)。但通过声明 toBuffer
如def toBuffer[A1 >: A]
(注意添加的类型参数 A1
),我们得到 toBuffer
的可能性返回 Buffer[Foo]
的实例:我们需要的只是明确设置 A1
到 Foo,或者让编译器推断它(如果在需要 toBuffer
的站点上调用 Buffer[Foo]
)。
我认为这解释了 toList
的原因和toBuffer
定义不同。现在的问题是toBuffer
是通用的,这会严重影响推理。
当你这样做时:
"ab-cd".split("-").toBuffer
你从来没有明确说过A1
是 String
,但是因为"ab-cd".split("-")
类型明确 Array[String]
,编译器知道 A
是 String
。它还知道A1 >: A
(在 toBuffer
中),并且没有任何进一步的约束,它将推断 A1
确切地说A
,换句话说String
。所以最后整个表达式返回 Buffer[String]
.
但事情是这样的:在 scala 中,类型推断发生在整个表达式中。当你有类似 a.b.c
的东西时,您可能期望 scala 会推断出确切的类型对于 a
,然后从中推断出 a.b
的确切类型,最后为a.b.c
。并非如此。类型推断推迟到整个表达式 a.b.c
(参见scala规范“6.26.4局部类型推断", "案例1:选择")
那么,回到你的问题,在表达式 "ab-cd".split("-").toBuffer.map(_.toBuffer)
中,子表达式 "ab-cd".split("-").toBuffer
未输入 Buffer[String]
, 但反而它的输入格式类似于 Buffer[A1] forSome A1 >: String
。换句话说,A1
不是固定的,我们只是带有约束 A1 >: String
到下一步的推理。下一步是map(_.toBuffer)
,其中map
定义为map[C](f: (B) ⇒ C): Buffer[B]
。这里B
实际上与 A1
相同,但此时A1
目前还不完全清楚,我们只知道A1 >: String
。我们的问题就在这里。编译器需要知道匿名函数的确切类型 (_.toBuffer)
(仅仅因为实例化 Function1[A,R]
需要知道 A
和 R
的确切类型,就像任何泛型类型一样)。所以你需要以某种方式明确地告诉他,因为它无法准确地推断出来。
这意味着您需要执行以下任一操作:
"ab-cd".split("-").toBuffer[String].map(_.toBuffer)
或者:
"ab-cd".split("-").toBuffer.map((_:String).toBuffer)
关于scala - toList 和 toBuffer 之间的类型推断不一致,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30659545/
在 ToList() 中指定具体类型是否有意义? , AsEnumerable()等方法? 威尔.ToList()执行速度比 .ToList() 快? 最佳答案 如果编译器推断出一种类型而您想要指定另
给定在内存中(不是 LINQ to SQL)类列表: List myItems = /*lots and lots of items*/; 我正在使用 GroupBy() 语句对其进行分组: myIt
我对此不是 100%,所以我需要专家的意见。 ConcurrentQueue queue = new ConcurrentQueue(); List listA = queue.ToArray().T
JDK 引入了一个 API Stream.toList() 和 JDK-8180352 。这是我尝试将其性能与现有 Collectors.toList 进行比较的基准测试代码: @BenchmarkM
说到性能,我应该使用 .ToList().Distinct() 还是 .Distinct().ToList() ? 两种扩展方法是否生成相同的 SQL 查询? 看起来第二种方法应该表现更好,但这是真的
当我调用它时: using (var db = new MyDbContext()) { var yy = db.Products.Select(xx => xx.Id); var i
我正在寻找这些 LINQ 表达式的确认/澄清: var context = new SomeCustomDbContext() // LINQ to Entities? var items = co
JDK 16 now includes a toList() method directly on Stream instances。在以前的Java版本中,您始终必须使用collect方法并提供Co
我真的很困惑如何解决这个问题 public bool DeleteVegetationZone(ref Assessment objAssessment, int VegetationZoneIDT
import numpy as np from scipy.sparse import lil_matrix 使用 numpy 我得到 test_mat = (np.ones((4,6))) test
当我有一个 IEnumerable我不知道它是否是一个列表(根据 List ),我必须枚举 IEnumerable以确保我不会枚举那个可枚举项两次(例如循环两次,或类似的事情)。 Resharper
我不知道 LinqQuery.ToList().Distinct() 和 LinqQuery.Distinct().ToList(); 对我来说有什么区别看起来一样。 考虑这个示例代码: List s
给定以下 LINQ 语句,哪个更有效? 一个: public List GetLatestLogEntries() { var logEntries = from entry in db.Lo
我正在尝试使用 Moq 模拟 Entity Framework DbContext,尤其是它的扩展方法 Add()、Tolist() 和 Find()。 我需要 Find() 和 ToList() 方
这个问题在这里已经有了答案: java 8 Collector is not a functional interface, who can tell why? (2 个回答) Java8: Usin
我只是在尝试新的 kotlin 语言。我遇到了生成无限列表的序列。我生成了一个序列并尝试打印前 10 个元素。但是下面的代码没有打印任何东西: fun main(args: Array) {
我们的代码库中都弹出了这两个代码 pandas.DataFrame.columns.values.tolist() pandas.DataFrame.columns.tolist() 这些总是相同的吗
这些 linq 查询有什么区别: Students.Where(x=>x.City == "Lahore").ToList(); Students.ToList().Where(x=>x.City =
我试图通过创建一个存储前 3 个值的单独变量来过滤数组列表。但是,在集合中出现错误。我对此很陌生,所以任何帮助都会很棒! public static ArrayList exerciseDetail(
我看到以下代码: using(var iterator = source.GetEnumerator()) {...} 哪里source是 IEnumerable . 执行上述操作与转换相比有何优势
我是一名优秀的程序员,十分优秀!