gpt4 book ai didi

java - (合作)列表的差异与 Scala 中的堆栈不同?

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:51:14 26 4
gpt4 key购买 nike

当我写这段代码时,我在 Scala 中遇到编译错误

var s: Stack[_ <: Number] = new Stack[Integer]; 
s.push(new Integer(1)); //compile-error: type mismatch; found :Integer required: _$bqjyh where type _$bqjyh <: Number
s.push(null); //compile-error: type mismatch; found : Null(null) required: _$2 where type _$2 <: Objects.Vehicle

由于通配符,这相当于 Java 中的协变集合;它的确切类型是未知的,所以我们不能向堆栈中添加任何东西。

但是使用列表我不会得到同样的错误:

   var list: List[_ <: Number] = Nil;
var intList : List[Integer] = new Integer(1) :: Nil;
list = intList ; //no error
list = new Float(2) :: vehicles; //even float allowed

现在我什至可以添加一个float,但实际上我认为list 是一个List Integers,所以不允许 Floats

1) 为什么列表允许这样做,而堆栈不允许?这是由于 cons (::) 运算符造成的吗?

2) 列表的类型是什么?它是动态的吗?

3) 为什么这在 Scala 中允许,而在 Java 中不允许?

4) 我可以向堆栈中添加一些东西吗? (null 无效,在 Java 中有效,因为泛型类型只允许引用类型)

最佳答案

::不是变异操作。这意味着 x :: xs将返回类型为 List[ commonSupertypeOf[ typeOf[x], elementTypeOf[xs] ] ] 的列表(这不是实际的 Scala 代码,但我希望我的观点得到理解),但它不会改变 xs 的类型.如果xs类型为 List[Float]x类型为 Integer ,然后是表达式 x :: xs将具有类型 List[Numeric] , 但 xs 的类型还是List[Float] , 所以没有任何问题。

add然而是一个变异操作。 xs.add(x)将添加 IntegerStack其类型为 Stack<Float> ,这显然是一个错误。

这解释了为什么做 x :: xs不危险。现在来解释为什么它会打字:

:: 的签名在 List[A] 上是:def :: [B >: A] (x: B) : List[B] .

这意味着对于任何类型 AB其中 BA 的父类(super class)型, ::给定一个 B 类型的值和类型列表 A将生成类型为 B 的列表.所以当你做一些someInteger :: someFloats , 编译器推断 BNumericAFloat一切正常。

在 Java 术语中是 <B supertypeOf A> List<B> prepend(B item)除了supertypeOf不是合法的 java。

关于java - (合作)列表的差异与 Scala 中的堆栈不同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3659301/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com