有人可以解釋為什么我不能在這種情況下更改 var 的值嗎?
fun main(args: Array<String>) {
var number = 3
changeNumber(number)
}
fun changeNumber(number: Int) {
number = 4 //here I see a warning "val cannot be reassigned"
}
uj5u.com熱心網友回復:
通過將“數字”傳遞給您的函式,您“按值傳遞”而不是“按參考傳遞”,該函式不知道您的主數字存盤在記憶體中的哪個位置,因此它無法更改它的值
您可以在此處和此處查看有關該主題的更多資訊
uj5u.com熱心網友回復:
絕對沒有辦法直接做到這一點。Kotlin 復制標量型別(Double、Float、Boolean、Int 等)的值。因此,任何內部更改都會丟失。
對于其他型別,Kotlin 復制傳遞給函式的引數參考。因此,引數的任何屬性/欄位更改也會更改呼叫者引數。
因此,對于此示例,您可以將您的號碼包含在 IntegerHolder 中,并更改保留在參考中的值。
data class IntegerHolder(
var v:Int
)
fun main() {
var a:IntegerHolder = IntegerHolder(2)
changeNumber(a)// Echange a value
print(a.v)
}
fun changeNumber(a:IntegerHolder) {
a.v = 5
}
uj5u.com熱心網友回復:
以防您發現其他答案有點令人困惑,我會補充一點,您不需要知道什么是標量或按值傳遞。這些是編譯器所做的底層優化,但不會改變代碼的邏輯行為。
Kotlin 僅適用于參考,而不適用于指標。您正在嘗試做的是您可以使用 C 或 C 等語言中的指標來做的事情。在這些語言中,您可以將指標傳遞給函式。指標不是變數的值,而是變數本身的記憶體地址,因此其他函式可以修改變數地址指向的內容。
Kotlin 完全不支持這一點。您只能傳遞參考。您正在傳遞變數指向的物件,但您不能對該變數本身做任何事情。您沒有傳遞該物件的副本,因此如果該物件是mutable,您可以更改其中的屬性值,并且原始函式可以通過再次檢查該物件來查看這些更改。但是許多簡單的類,如 Int、Float、Double 和 String 都是不可變的,所以在邏輯上你不傳遞副本是不相關的(這就是為什么 Kotlin 底層可以通過傳遞其中一些的實際值來優化,稱為“行內類”)。
針對此限制的幾個解決方法:
- 可變包裝類。使用它作為你的變數型別和函式引數型別。
data class IntWrapper(var value: Int)
fun main(args: Array<String>) {
val number = IntWrapper(3)
changeNumber(number)
println(number.value)
}
fun changeNumber(number: IntWrapper) {
number.value = 4
}
- 傳遞一個可以修改變數的函式。setter 函式是更改變數的函式的引數。(指標和我們在這里所做的不同之處在于,改變變數的函式實際上并不知道它正在改變一個變數。它只是呼叫傳遞給它的函式,它可以用提供的函式做任何它想做的事情數字。)
fun main(args: Array<String>) {
var number = 3
changeNumber { number = it }
println(number)
}
fun changeNumber(numberSetter: (Int)->Unit) {
numberSetter(4)
}
但是,您并不經常需要執行其中一項操作。撰寫提供回傳值的函式更為常見,您可以使用該值重新分配變數。這種策略更加穩健。它提供了更好的封裝,這自然使您的代碼不易出錯。
fun main(args: Array<String>) {
var number = 3
number = produceNewNumber()
println(number)
}
fun produceNewNumber(): Int {
return 4
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/523746.html
標籤:科特林
