我从一本有效的书中提取了一个简单的测试程序:
def main(args: Array[String]) {
val monTabEntiers = new Array[Int](30);
val monTabEntiersInit = Array(1, 2, 5, 6);
val monTabChaine = new Array[String](30);
val lesSaisons = Array("été", "automne", "printemps", "hiver");
println(monTabEntiers(0));
println(monTabEntiersInit(0));
println(monTabChaine(0));
println(lesSaisons(0));
monTabEntiersInit.update(0, 15);
println(monTabEntiersInit(0));
...
但我决定改变它,因为我不喜欢松散类型的变量。
val monTabEntiers:Array[Int] = new Array(30);
val monTabEntiersInit = Array(1, 2, 5, 6);
val monTabChaine:Array[String] = new Array(30);
val lesSaisons:Array[String] = Array("été", "automne", "printemps", "hiver");
但我不知道如何处理 monTabEntiersInit
来声明(即使它的名字不是它的目标)一个 Array 任何东西。
我该如何更改?
val monTabEntiersInit = Array(1, 2, 5, 6);
我尝试过但没有成功:
val monTabEntiersInit:Array = Array(1, 2, 5, 6);
Refused : type parameter is asked.
val monTabEntiersInit:Array[_] = Array(1, 2, 5, 6);
// fails on line :
monTabEntiersInit.update(0, 15);
found : Int(15)
required: _$1
总而言之,我正在寻找这种类似 Java 的声明(大致编写,我没有检查下面的语法正确性):
List<?> monTabEntiersInit = new ArrayList<?>(List.of(1, 2, 5, 6));
拒绝这个:
var monTabEntiersInit = new ArrayList<?>(List.of(1, 2, 5, 6));
答案 0 :(得分:3)
正确的注解是
val monTabEntiersInit: Array[Int] = Array(1, 2, 5, 6)
如果您真的希望 monTabEntiersInit
保存任何可能的值,那么简单的答案是使用 Any
:
val monTabEntiersInit: array[Any] = Array(1, 2, 5, 6)
然而,这几乎总是一个坏主意,最好收紧类型。如果您想保存两种可能类型中的一种,则可以使用 Either
。如果您需要更多值,请考虑使用特征:
trait Value
case class StringValue(s: String) extends Value
case class IntValue(i: Int) extends Value
case class DoubleValue(d: Double) extends Value
val monTabEntiersInit: array[Value] = ...
然后您可以使用 match
计算出您要处理的值。
monTabEntiersInit(0) match {
case StringValue(s) =>
// process s
case IntValue(i) =>
// process i
case DoubleValue(d) =>
// process d
}
答案 1 :(得分:1)
首先,您的变量不是“松散输入”。类型注解在 Scala 中是可选的,但它仍然是严格类型的。
val monTabEntiersInit = Array(1, 2, 5, 6) // you don't need semi-colons
声明一个 Int
数组,它比您最终得到的 Array[Any]
“松散输入”要少得多。后者太松散了,几乎总是应该避免:使用 Any
完全绕过了类型系统并使集合在很大程度上无法使用。
最后,您的问题不在于类型声明,而在于适当的变异变量。这是非常不寻常的,并且在 scala 中不受欢迎,而不是“scala 方式”。你应该避免这种情况。 注意,虽然
val foo: Array[_] = Array(1,2,3)
foo.update(0,0)
不起作用,像这样:
val x = Array(1,2,3)
val y = x.updated(0,0) // Still Array[Int]
val z = x.updated(1, "one") // Now Array[Any]
不仅可以工作,而且是线程安全和引用透明的,而且还可以正确跟踪结果数组。
一般来说,除了您希望优化最后几毫秒性能的一些高度专业化的情况外,不要使用 Array
,使用 Seq
/List
(对于顺序集合)、LazyList
/Iterator
(用于流式传输和/或迭代一次语义)、IndexedSeq
/Vector
(用于随机访问)。并且不要在任何地方改变事物。那只是……糟糕。
总而言之,一些在 Scala 中几乎通用的“经验法则”:
Any
Array
)答案 2 :(得分:0)
它甚至不能在 Java 中编译如下:
ArrayList<?> list = new ArrayList(10);
list.set(0, "abc");
相反,你应该写成:
ArrayList<Object> list = new ArrayList<>(10);
list.set(0, "abc");
在Scala中:
val monTabEntiersInit:Array<Any> = Array(1, 2, 5, 6)