加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

选择性地禁用Scala中的包含? (正确输入List.contains)

发布时间:2020-12-16 09:41:30 所属栏目:安全 来源:网络整理
导读:List("a").contains(5) 因为Int不能包含在String列表中,所以在编译时应该会生成一个错误,但是它不会。 它浪费和默默地测试列表中包含的每个String等于5,这永远不会是真的(“Scala”中的“5”从不等于5)。 这被命名为“the ‘contains’ problem”。而some
List("a").contains(5)

因为Int不能包含在String列表中,所以在编译时应该会生成一个错误,但是它不会。

它浪费和默默地测试列表中包含的每个String等于5,这永远不会是真的(“Scala”中的“5”从不等于5)。

这被命名为“the ‘contains’ problem”。而some have implied认为,如果一个类型系统无法正确地键入这样的语义,那么为什么要进行额外的强化类型的努力。所以我认为这是一个重要的问题要解决。

类型参数化B>:List.contains的A输入任何类型为类型A的超类型(列表中包含的元素的类型)。

trait List[+A] {
   def contains[B >: A](x: B): Boolean
}

这种类型的参数化是必要的,因为A声明在类型A上的列表是covariant,因此A不能用于逆变位置,即作为输入参数的类型。协变列表(必须是不可变的)是不变列表(可以是可变的)的much more powerful for extension。

A是上述问题示例中的String,但Int不是String的超类型,所以发生了什么? Scala中的implicit subsumption决定了Any是String和Int之间的相互超类型。

Scala的创建者Martin Odersky,suggested表示,修复将是将输入类型B限制为只有具有Any的equals方法的那些类型。

trait List[+A] {
   def contains[B >: A : Eq](x: B): Boolean
}

但是这并不能解决问题,因为两种类型(其中输入类型不是列表元素的类型的超类型)可能具有相互超类型,它是Sub的子类型,也就是Eq的子类型。因此,它将编译没有错误,并且不正确类型的语义将保留。

因为隐含的包含是为什么下面的例子适用于任何一个工作。而且,当接收站点(例如,作为函数参数传递)具有相互超类型(甚至可能不是任何)的正确类型语义时,我们不希望被强制使用类型转换。

trait List[+A] {
   def ::[B >: A](x: B): List[B]
}

val x : List[Any] = List("a",5) // see[1]

[1] List.apply calls the :: operator。

所以我的问题是什么是最好的解决这个问题?

我的初步结论是,隐式收入应该在定义网站上关闭,否则语义不能正确输入。我将提供一个答案,显示如何在方法定义站点关闭隐含的包含。是否有替代解决方案?

请注意这个问题是一般的,而不是孤立到列表。

更新:我有filed an improvement request,开始了scala discussion thread on this.我还在Kim Stebel和Peter Schmitz的回答中增加了评论,表明他们的答案有错误的功能。因此没有解决办法。另外在上述讨论的线索,我解释了为什么我认为soc的答案是不正确的。

解决方法

我想我有一个合法的解决方案,至少在这里发布的一些问题 – 我的意思是List(“1”)的问题包含(1):
https://docs.google.com/document/d/1sC42GKY7WvztXzgWPGDqFukZ0smZFmNnQksD_lJzm20/edit

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读