scala - 如何定义一个参数类型不能为 Any 的 scala 方法

标签 scala types type-constraints

在下面的例子中,我想定义一个 contains如果 a 则无法编译的方法和 b不是相同的基本类型。

  • contains1实现,如果 aSeq[Int] b 是 String , T导出为 Any , 并编译。这不是我想要的。
  • contains2实现,如果 aSeq[Int] b 是 String ,然后它不会编译。这种行为是我想要的。

  • def contains1[T](a: Seq[T], b: T): Boolean = a.contains(b)
    
    println(contains1(Seq(1,2,3), "four")) // false
    
    def contains2[T: Ordering](a: Seq[T], b: T): Boolean = a.contains(b)
    
    println(contains2(Seq(1,2,3), "four")) // compilation error
    // cmd7.sc:1: No implicit Ordering defined for Any.
    // val res7 = isMatched(Seq(1,2,3), "s")
                        ^
    // Compilation Failed
    

    但是,有没有更简单的方法来实现与 contains2 中相同的行为? ? Ordering上下文绑定(bind)让我感到困惑,因为该方法与排序/排序完全无关。

    最佳答案

    您可以使用 广义类型约束 接线员 =:= .

    例如:

    def contains[A,B](a: Seq[A], b: B)(implicit evidence: A =:= B): Boolean = a.contains(b)
    

    进而:
    println(contains1(Seq(1,2,3), "four")) //fails with Cannot prove that Int =:= String.
    println(contains1(Seq("one"), "four")) //returns false
    println(contains1(Seq("one", "four"), "four")) //true
    

    更多关于广义类型约束 herehere .

    正如 LuisMiguelMejíaSuárez 所注意到的,您也可以考虑使用 B <:< A而不是 A =:= B .我不会详细说明这两者之间的区别,因为它在链接的答案和文章中有所描述,但简而言之,<:<也将允许所有 BA 的子类型, 而 =:=需要类型完全匹配。

    关于scala - 如何定义一个参数类型不能为 Any 的 scala 方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56637005/

    相关文章:

    php - 在 MySQL 数据库中存储纬度和经度值的问题

    perl - Moose 从单个参数构造对象

    scala - 如何设置隐式转换以允许数字类型之间的算术?

    Scala - 这个 map + case 语法是什么?

    c++ - 如何检查名称是 C++17 中的别名还是引用?

    c++ - GLSL bool 值的大小是多少

    haskell - 为什么 Haskell 没有在函数签名中推断数据类型的类型类?

    c# - 如何指定不实现特定接口(interface)的类型参数?

    scala - 如何使用 sbt 从发布中排除包?

    java - Univocity 解析器 - 迭代器方式生成 scala 案例类