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

scala – “可以用`_`的等效用法替换`forSome`的所有用法的真实

发布时间:2020-12-16 18:41:20 所属栏目:安全 来源:网络整理
导读:我看到了问题的答案: Can all usages of forSome be replaced by an equivalent usage of _ ?, 但不明白什么是“_”不能用来代替“forSome”的真实情况. 我在 Programming in Scala书中读过: Existential types are a fully supported part of the languag
我看到了问题的答案: Can all usages of forSome be replaced by an equivalent usage of _?,
但不明白什么是“_”不能用来代替“forSome”的真实情况.
我在 Programming in Scala书中读过:

Existential types are a fully supported part of the language,but in
practice they are mainly used when accessing Java types from Scala.
I created Scala project and referenced Java one to it:

斯卡拉:

object Main {
  def main(args: Array[String]): Unit = {
    type Test = java.util.Collection[T] forSome { type T }
    val contents: Test = (new Wild).contents

    type Test2 = java.util.Collection[_]
    val contents2: Test2 = (new Wild).contents

    //    foo((new Wild).contents2) // won't compile

    foo1((new Wild).contents2)
    foo1((new Wild).contents3)

    foo2((new Wild).contents3)
  }

  def foo(xs: java.util.Map[T,T] forSome { type T }) {}
  def foo1(xs: java.util.Map[_,_]) {}
  def foo2(xs: java.util.Map[_,_ <: java.lang.Number]) {}
}

Java的:

public class Wild {
    public Collection<?> contents() {
        return null;
    }
    public Map<?,?> contents2() {
        return null;
    }
    public Map<?,? extends Number> contents3() {
        return null;
    }
}

在所有情况下,我都可以用“_”替换“forSome”.
那么“forSome”是必要的真实案例是什么?请提供简单的工作示例.

解决方法

这是一个相当简单的例子.

val listOfSets: List[Set[T]] forSome { type T } = List(Set(1,2,3),Set(4,5,6))

请注意,我只能将相同包含类型的集合存储到列表中.我无法做到,例如这个:

val listOfSets: List[Set[T]] forSome { type T } = List(Set(1,Set("a","b","c"))

如果没有forSome,listOfSets的类型是无法表达的.确实,

val listOfSets2: List[Set[_]]

相当于

val listOfSets2: List[Set[T] forSome { type T }]

这意味着列表可以包含不同类型的集合,因此这两个工作:

val listOfSets2: List[Set[_]] = List(Set(1,6))
val listOfSets2: List[Set[_]] = List(Set(1,"c"))

有趣的是,如果您将Scala解释器作为scala -feature运行并尝试执行此答案中的第一行代码,您将获得有关带有通配符的存在类型的无法表达的警告:

scala> val listOfSets: List[Set[T]] forSome { type T } = List(Set(1,6))
<console>:7: warning: the existential type List[Set[T]] forSome { type T },which cannot be expressed by wildcards,should be enabled
by making the implicit value scala.language.existentials visible.
This can be achieved by adding the import clause 'import scala.language.existentials'
or by setting the compiler option -language:existentials.
See the Scala docs for value scala.language.existentials for a discussion
why the feature should be explicitly enabled.
       val listOfSets: List[Set[T]] forSome { type T } = List(Set(1,6))
                                     ^
listOfSets: List[Set[T]] forSome { type T } = List(Set(1,6))

还有另一个例子.假设您要将类映射到该类的单个实例.这可以用这种类型表示:

val classInstanceMap: Map[Class[T],T] forSome { type T }

如果没有forSome,你就无法写出正确的类型 – 没有其他方法来“关联”键和值的类型.例如,这种类型带有通配符:

val invalidClassInstanceMap: Map[Class[_],_]

相当于

val invalidClassInstanceMap: Map[Class[K] forSome { type K },V] forSome { type V }

这里K和V根本没有关系,而且,对于任意T,键可以是Class [T]的任意实例,但是所有值都应该具有相同的类型.

(编辑:李大同)

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

    推荐文章
      热点阅读