【问题标题】:Enforce Scala Seq to use a single type only (no LUB)强制 Scala Seq 仅使用单一类型(无 LUB)
【发布时间】:2017-04-02 08:23:58
【问题描述】:

我想在 Scala 中创建和使用 Seq[T] 集合 并确保它只使用一种类型。所以如果我使用:

val l = List(1, 2, 2.0)

应该出现编译时错误 - List 元素应该都是 Double 或全部Int

【问题讨论】:

  • 也许你会觉得这很有趣:eed3si9n.com/stricter-scala-with-ynolub
  • 从响应中,似乎避免 LUB 要求我在声明集合时指定类型或更改编译器行为。我在想一些神奇的类型级编程可以解决这个问题。感谢 @Jubobs 和 stefanobaghino 的帮助。
  • 对于任何 fixed 数量的参数都有一种标准方法,但我认为没有一个用于可变参数的方法。
  • 是的。我已经用两个参数和 =:= 类型级运算符完成了这项工作。对于收藏,我还没有找到方法。感谢您的意见。

标签: scala collections compile-time typechecking


【解决方案1】:

考虑-Xlint:infer-any编译器flag

当类型参数被推断为Any时发出警告

结合致命警告至少可以防止推断出Any 的最坏 LUB 场景

scala -Xlint:infer-any -Werror -e 'List(42, 3.14, "picard")'
warning: a type was inferred to be `Any`; this may indicate a programming error.
List(42, 3.14, "picard")
^
error: No warnings can be incurred under -Werror.

但是请注意,如果 LUB 比 Any 窄,这将无济于事,例如

scala -Xlint:infer-any -Werror -e 'Vector(List(1), Set(2))'

不发出警告。另一个可能有帮助的标志是-Wnumeric-widen

当数字变宽时发出警告。

例如

scala -Wnumeric-widen -Xlint:infer-any -Werror -e 'def f(i: Int, d: Double): List[Double] = List(i, d)'
warning: implicit numeric widening
def f(i: Int, d: Double): List[Double] = List(i, d)
                                              ^
error: No warnings can be incurred under -Werror.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-13
    • 2016-06-28
    • 1970-01-01
    • 2022-08-23
    相关资源
    最近更新 更多