Kotlin函数参数不允许使用val或var,该如何限制参数在函数体内不被修改?

众所周知,在C++中广泛应用了const关键字,const可以用在函数参数处保证参数不被修改。 但在更先进的语言Kotlin中,居然不允许val修饰函…
关注者
4
被浏览
9,611

4 个回答

提问有错误, 参数默认是val,想通过方法来修改对应方法参数值不可行。

早期的 Kotlin 版本函数参数是可以定义成 var 的,不过后来官方明确了「函数参数都是不可变」这一点。在这篇更新日志里可以找到说明:

The main reason is that this was confusing: people tend to think that
this means passing a parameter by reference, which we do not support
(it is costly at runtime). Another source of confusion is primary
constructors: “val” or “var” in a constructor declaration means
something different from the same thing if a function declarations
(namely, it creates a property). Also, we all know that mutating
parameters is no good style, so writing “val” or “var” in front of a
parameter in a function, catch block of for-loop is no longer allowed.

参考一些回答:


原文链接: kotlin 主构造函数的参数可以加上var val,普通函数却不能用var或者val

在 Kotlin 中,可以通过三种不同的方式定义变量。

var

sntax : var identifier[:type] = value

在 Kotlin 中提及类型是可选的,因为编译器足够聪明,可以根据值推断它。

一旦使用 var 关键字创建变量,就可以读取值、分配新值并改变值。 让我们看一个例子来说明清楚。

data class Mutable(var mute: Int)
fun main() {
    var varDemo = Mutable(10) /* Initialization */
    println(varDemo)
    varDemo = Mutable(20)     /* Assigning a new value */
    println(varDemo)
    varDemo.mute = 40		  /* Mutating value */
    println(varDemo)
}

在上面的示例中,varDemo 使用对象 Mutable(10) 进行初始化,并为其分配了一个新对象 Mutable(20),最后,通过将 40 分配给其成员 mute,该值本身发生了变异


val

sntax : val identifier[:type] = value

一旦使用 val 关键字创建变量,就可以读取值并改变值,但不能分配新值。 让我们看一个例子来说明清楚。

data class Mutable(var mute: Int)
fun main() {
    val valDemo = Mutable(10) /* Initialization */
    println(valDemo)
    valDemo.mute = 20		  /* Mutating value */
    println(valDemo)
    //valDemo = Mutable(30)   /* Throw an error */
}

在上面的例子中,valDemo 被初始化,并且值被改变,但是分配一个新的对象 Mutable(30) 会抛出一个错误 val cannot be reassigned。

一个常见的误解是 val 是不可变的,但实际上并非如此,因为它允许值的突变。 可以通过将 const 修饰符添加到 val 关键字来创建不可变值。


const val

将 const 修饰符添加到 val 关键字会创建一个编译时常量,这意味着必须在编译时知道该值。 由于这些限制, const val 具有以下限制。

  • 仅允许使用 String 或原始类型初始化 const val。
data class Mutable(var  mute:Int)
const val CONST_VAL_VALID = 10
const val CONST_VAL_VALID_TOO = "compile-time"
// const val CONST_VAL_INVALID = Mutable(10) /* Throw an error */
fun main() {
    println(CONST_VAL_VALID)
    println(CONST_VAL_VALID_TOO)
}

在上面的示例中,将 Mutable(10) 对象分配给 const val 将引发错误 Const val has type Mutable。 只允许使用原语和字符串

  • 仅允许在顶级范围内或对象或伴生对象的成员中定义 const val。
class Mutable() {
    // const val CONST_VAL_INVALID = 10 /* Throw an error */
    fun runTimeFunc() {
        // const val CONST_VAL_INVALID = 10 /* Throw an error */
    companion object {
        const val CONST_VAL_VALID_HERE = 10
const val CONST_VAL_VALID = 10