Arrays 仅通过初始化就可以在Kotlin中声明大小为的数组吗?
我没有发现如何在Kotlin中声明具有预定义大小的数组而不初始化它 这没关系:Arrays 仅通过初始化就可以在Kotlin中声明大小为的数组吗?,arrays,kotlin,Arrays,Kotlin,我没有发现如何在Kotlin中声明具有预定义大小的数组而不初始化它 这没关系: lateinit var v:Array<Int> lateinit变量v:Array 但我猜不能在数组类型中设置大小规格 如果需要指定尺寸。我们必须做到: var v2:Array<Int> = Array<Int>(2){5} var v2:Array=Array(2){5} 在这种情况下,向量的所有元素都等于5 下面是一个类和数组的示例: data class But
lateinit var v:Array<Int>
lateinit变量v:Array
但我猜不能在数组类型中设置大小规格
如果需要指定尺寸。我们必须做到:
var v2:Array<Int> = Array<Int>(2){5}
var v2:Array=Array(2){5}
在这种情况下,向量的所有元素都等于5
下面是一个类和数组的示例:
data class But(
val fufo: Int=0,
val tp: Int = 1
)
typealias ArBut = Array<But>
data class CArray (
var arrayC: ArBut = ArBut(2){But()}
)
val a = CArray(arrayOf(But(2,2),But(5,4),But(3,3)))
println(a.arrayC[2])
数据类,但(
val fufo:Int=0,
val-tp:Int=1
)
typealias ArBut=数组
数据类CArray(
var arrayC:ArBut=ArBut(2){But()}
)
val a=CArray(数组(但是(2,2),但是(5,4),但是(3,3)))
println(a.arrayC[2])
它起作用了!有趣的是,初始化不是类型的一部分,您可以在类中放置任意大小的数组,而无需边界检查。如果尺寸是类型规格的一部分,则会有所不同
现在是一个例子,使用矩阵。注意,语法有点复杂
data class CMatr (
val matrC: Array<ArBut> = Array<ArBut>(2){ArBut(0){But()}}
)
val m = CMatr(arrayOf( arrayOf(But(2,2),But(5,4)),
arrayOf(But(-2,2),But(3,4)), arrayOf(But(1,1),But(5,3)) ))
println(m.matrC[2][1]) // Also works!
数据类CMatr(
val matrC:Array=Array(2){ArBut(0){But()}
)
valm=CMatr(arrayOf(arrayOf(But(2,2),But(5,4)),
arrayOf(But(-2,2),But(3,4)),arrayOf(But(1,1),But(5,3)))
println(m.matrC[2][1])//同样有效!
是否无法将大小放入数组类型规范中,或者我遗漏了什么?对于基本类型: 你就是这样做的。不使用kotlin内置函数,如
intArrayOf(args…
,而是使用IntArray
以下是一个例子:
// Array of integers of a size of N
val arr = IntArray(N)
// Array of integers of a size of N initialized with a default value of 2
val arr = IntArray(N) { 2 }
参考类型:
对于引用类型对象,可以执行以下操作
val cars: Array<Car?> = arrayOfNulls(N)
//returns an array of nullable Car objects with null values and size of N
val cars:Array=arrayOfNulls(N)
//返回具有空值且大小为N的可空汽车对象数组
如果要创建非空对象数组,则需要在创建数组时初始化它们
val cars: Array<Car> = Array<Car>(5){ Car() }
//returns an array of non nullable car objects that has been initialized
//with the method you provided in this case Car constructor with size of N
val cars:Array=Array(5){Car()}
//返回已初始化的不可为空的car对象数组
//使用本例中提供的方法,使用大小为N的Car构造函数
对于您的示例,对于但是类,您可以使用:
var arrayC:Array=arrayOfNulls(2)//无需初始化
或:
var arrayC:Array=Array(2){But()}//需要初始化
但无论哪种方法都不会阻止您创建更大数组的新实例并将其分配给变量
编辑
在我看来,有两种方法可以解决这个问题
第一种方法是将数组属性声明为var,并在setter中测试赋值:
class Test {
var array: Array<Int> = Array(3){0}
set(value) {
if(value.size > 3)
throw IllegalArgumentException("The array size cannot be bigger than 3")
field = value
}
}
fun main(args: Array<String>) {
val test = Test()
test.array = arrayOf(0, 1, 2) // Ok
test.array = arrayOf(0, 1, 2, 3) // throws IllegalArgumentException
}
类测试{
变量数组:数组=数组(3){0}
设置(值){
如果(value.size>3)
抛出IllegalArgumentException(“数组大小不能大于3”)
字段=值
}
}
趣味主线(args:Array){
val测试=测试()
test.array=arrayOf(0,1,2)//确定
test.array=arrayOf(0,1,2,3)//抛出IllegalArgumentException
}
或者,如果您想在编译时处理它,您可以将属性设置为final,并用您想要的大小初始化它
class Test {
val array: Array<Int> = Array(3){0}
}
fun main(args: Array<String>) {
val test = Test()
for (i in 0..2) // Ok
test.array[i] = i
for (i in 0..3) // throws ArrayIndexOutOfBoundsException
test.array[i] = i
test.array = arrayOf(0, 1, 2, 3) // compile time error: Val cannot be reassigned
}
类测试{
val数组:数组=数组(3){0}
}
趣味主线(args:Array){
val测试=测试()
对于(0..2中的i)//确定
test.array[i]=i
for(0..3中的i)//抛出ArrayIndexOutOfBoundsException
test.array[i]=i
test.array=arrayOf(0,1,2,3)//编译时错误:无法重新分配Val
}
是的,在Kotlin中,数组大小不是其类型的一部分,因此无法将其作为一部分。这不是特定于阵列的;类型不能以任何方式依赖于Kotlin中的值
类型中的大小初始化允许在运行时检查绑定冲突
数组边界总是在JVM上的运行时检查。即使编译器不想这样做,它也做不到。这是正确的,但只适用于一些基本类型(字节
,浮点
,双精度
,整数
,长
,字符
和,布尔
)。不是字符串
。您的第二个示例可以编写一个val-arr=IntArray(N){2}
@PauloBuchsbaum作为参考数组,使用类似val-arr=Array(N){'}
或val-arr=Array(N){null}
的内容,但我的观点是允许程序员在声明类型部分而不是在初始化部分中选择数组大小。它可以保护程序员免受与数组大小相关的错误分配。是的,我知道,但我相信这将是程序员在类型中选择大小而不是通过初始化的有用选择。类型中的大小初始化允许在运行时检查绑定冲突。它可以通过类型定义的一部分来避免逻辑错误。这在我的项目中确实发生过。我明白了。我已经编辑了我的答案,添加了一些可能的解决方案。我知道数组边界是在运行时检查的,但在另一点上。如果指定的数组比投影的数组长,则无法签入Kotlin
。显然,当试图在现有索引之外使用组件时,每种语言(实际上)都会给出错误。旧语言可以对大小数组进行编译器检查,只要使用的大小是常量(因此在编译器时已知),想象一个具有3D点数组数组的结构。除非使用类定义3D,否则无法在编译器时间内定义每个点的长度为3。