返回介绍

数学基础

统计学习

深度学习

工具

Scala

四、通配类型

发布于 2023-07-17 23:38:22 字数 3417 浏览 0 评论 0 收藏 0

  1. 所有 Java 类型在 Scala 中都有对等的概念。这是必要的,因为只有这样 Scala 代码才能访问任何合法的 Java 类。但是在某些情况下,如 Java 中的 Iterator<?> 或者 Iterator<? Extends Component>Java 通配类型,scala 使用一种额外的叫做通配类型 wildcard type 来表示。

    scala 中的通配类型的编写方式是:通过占位符语法,类似函数字面量的简写方式。在函数字面量中,可以通过下划线 _ 代替表达式,如 ( _ + 1) 等价于 ( x => x + 1) 。通配类型也是相同的理念,但是它针对的是类型而不是表达式。如果你写下 Iterator[_], 则这里的下划线 _ 就是代表某个类型。这个类型声明表示的是一个元素类型未知的 Iterator

  2. 你也可以在占位符语法中插入类型上界或类型下界,只需要在下划线之后添加即可,使用和类型参数相同的 <: 语法:

    
    
    xxxxxxxxxx
    Iterator[ _ <: Component] // 表示一个元素类型未知的 Iterator,但是元素类型必须是 Component 的子类
  3. 在简单的使用中,可以忽略通配符,直接调用集合的方法:

    
    
    xxxxxxxxxx
    // java 代码 public class ABC{ public Collection<?> contents(){ Collection<String> s = new Vector<String> (); s.add("a"); s.add("b"); return s; } }

    Scala 中可以直接使用:

    
    
    xxxxxxxxxx
    val contents = (new ABC).contents // 返回 java.util.Collection[_]

    对于更复杂的情况,需要做更多额外的工作:

    
    
    xxxxxxxxxx
    val iter = (new Wild).contents.iterator val set = scala.collections.mutable.Set.empty[] // 这里应该填什么类型?不知道 while(iter.hasMore){ set += iter.next() }

    有两个技巧来解决该问题:

    • 给方法分配一个类型参数来表示这个通配类型。
    • 不用从方法返回通配符,而是返回一个对每个占位符都定义了抽象成员的对象
    ​x
    abstract class CCC{
      type Elem
      val set:scala.collections.mutable.Set[Elem]
    }
    ​
    def f(javaSet: java.util.Collection[T]): CCC = {
      val s = scala.collection.mutable.Set.empty[T]   // 现在可以用 T 表示通配类型
      val iter = javaSet.contents.iterator
      while(iter.hasMore){
        set += iter.next()
      }
      return new CCC{  // 返回一个对象
        type Elem = T
        val set = s
      }
    }

    由于 scala 中通配类型的使用比较繁琐,因此你也可以在一开始就是使用抽象成员而避免使用通配类型。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文