class Adult: Resident {
constructor(name: String, id:String): super(name, id)
var email: String? = null
var address: MutableList<String>? = null
fun setAddress(s: String){
address = s.split("\\n".toRegex()).toMutableList()
}
}
并且这个测试用例失败了,因为
时 b.address = a.address
,b.address?.add("Universe"
)也被添加到对象a
。
fun test6() {
val a = Adult("Roger Widdoff","604119274")
val b = Adult("Kathleen Craig","647022192")
a.setAddress("123 Main Street\nAnytown, Country")
assertEquals(2,a.address?.size)
b.address = a.address
b.address?.add("Universe")
assertEquals(3,b.address?.size)
assertEquals(2,a.address?.size)
}
我真的很困惑为什么会这样,我已经搜索了几个小时的文档。任何人都可以将我链接到某个地方来解决这个问题谢谢。
答案 0 :(得分:4)
使用int main()
{
char* fileName;
int average;
getFilename(fileName);
readFile(fileName);
displayAverage(average);
return 0;
}
,您将创建一个指向现有对象实例的变量(将其视为指向存储它的内存的指针)。它没有创建副本。因此,您有两个变量b.address = a.address
和b.address
指向同一个对象,即a.address
的实例。无论您使用哪个变量,都会对这个实例进行任何更改。
这不是Kotlin的“特色”,它是一个概括的概念,被描述为Aliasing:
在计算中,别名描述了一种情况,即可以通过程序中的不同符号名称访问内存中的数据位置。因此,通过一个名称修改数据会隐式修改与所有别名相关联的值,这可能是程序员不期望的。
通常情况下,我建议您将列表类型更改为只读MutableList<String>
,这样可以避免这个错误的测试用例。由于您无法修改测试用例,因此可以使用创建列表副本的自定义getter来解决问题:
List
答案 1 :(得分:0)
如果您想在b.address = a.address
上“复制”,则应避免使用mutableList
。而是使用immutable
一个:
class Adult {
constructor(name: String, id: String)
var email: String? = null
var address: List<String> = emptyList()
fun setAddress(s: String) {
address = s.split("\\n".toRegex()).toMutableList()
}
}
class AdultTest {
@Test
fun test6() {
val a = Adult("Roger Widdoff","604119274")
val b = Adult("Kathleen Craig","647022192")
a.setAddress("123 Main Street\nAnytown, Country")
assertEquals(2,a.address.size)
b.address = a.address
b.address += "Universe"
assertEquals(3,b.address.size)
assertEquals(2,a.address.size)
}
}
这里有address
作为不可变列表。首先用b.address = a.address
复制它只是指向同一个列表。但b.address += "Universe"
只会更改b