【问题标题】:What is the difference between var and val in Kotlin?Kotlin 中的 var 和 val 有什么区别?
【发布时间】:2017-10-27 06:13:10
【问题描述】:

varval 在 Kotlin 中有什么区别?

我已经浏览了这个链接:

KotlinLang: Properties and Fields

如该链接所述:

只读属性声明的完整语法不同于 以两种方式可变的一种:它以 val 而不是 var 开头,并且确实 不允许二传手。

但就在之前有一个使用 setter 的示例。

fun copyAddress(address: Address): Address {
    val result = Address() // there's no 'new' keyword in Kotlin
    result.name = address.name // accessors are called
    result.street = address.street
    // ...
    return result
}

varval 之间的确切区别是什么?

为什么我们两者都需要?

不是 Variables in Kotlin, differences with Java: 'var' vs. 'val'? 的重复,因为我询问的是与文档中特定示例相关的疑问,而不仅仅是一般性。

【问题讨论】:

标签: kotlin variables


【解决方案1】:

在您的代码中result 没有改变,它的var 属性正在改变。参考下面的cmets:

fun copyAddress(address: Address): Address {
    val result = Address() // result is read only
    result.name = address.name // but not their properties.
    result.street = address.street
    // ...
    return result
}

val 与 java 中的 final 修饰符相同。您可能应该知道,我们不能再次分配给 final 变量,但可以更改其属性。

【讨论】:

  • 函数和类或主构造函数中的val和var含义不同?
  • @Nothing 不,到处都一样。
  • 但是当我在类中用 var 声明变量时,它需要初始化,因为它声明了属性。但是在函数中它不需要初始化为什么?
  • 因为当类加载到内存中时,它的属性也会被评估。但是在函数中,变量在函数代码执行时被评估。
  • 是指在函数内部还是在类内部,valvar这两个关键字都是用来声明属性的?不可变?
【解决方案2】:

var 与任何其他语言一样是一个变量。 例如。

var price: Double

另一方面,val 为您提供了引用功能。 例如。

val CONTINENTS = 7
// You refer this to get constant value 7. In this case, val acts as access
// specifier final in Java

和,

val Int.absolute: Int
    get() {
        return Math.abs(this)
    }
// You refer to the newly create 'method' which provides absolute value 
// of your integer

println(-5.absolute) // O.P: 5

【讨论】:

    【解决方案3】:

    如果我们使用val 声明变量,那么它将是只读变量。我们无法改变它的价值。这就像 Javafinal 变量。我是immutable

    但是如果我们使用var 声明变量,那么它将是一个我们可以读取写入的变量。我们可以改变它的价值。我是mutable

    data class Name(val firstName: String, var lastName: String)
    
    fun printName(name: Name): Name {
        val myName = Name("Avijit", "Karmakar") // myName variable is read only
        // firstName variable is read-only. 
        //You will get a compile time error. Val cannot be reassigned.
        myName.firstName = myName.firstName
        // lastName variable can be read and write as it's a var.
        myName.lastName = myName.lastName
        return myName
    }
    

    val 最近不能被关键字lateinit 初始化,但非原始var 可以最近被关键字lateinit 初始化。

    【讨论】:

    • 函数和类或主构造函数中的val和var含义不同?
    【解决方案4】:

    你可以很容易地认为它是:

    var 用于设置器(值会改变)。

    val 用于 getter(只读,值不会改变)。

    【讨论】:

      【解决方案5】:

      简单地说, var(可变)和 val(Java 中的不可变值(final 修饰符))

      var x:Int=3
      x *= x
      
      //gives compilation error (val cannot be re-assigned)
      val y: Int = 6
      y*=y
      

      【讨论】:

        【解决方案6】:

        在 Kotlin 中,val 是 immutable,var 是 mutable

        【讨论】:

          【解决方案7】:

          valvar 都用于声明变量。

          var类似于general变量,在kotlin中称为可变变量,可以多次赋值。

          val 类似于 Final 变量,在 kotlin 中被称为不可变,只能被初始化一次。

          有关valvar的更多信息,请参阅以下链接

          http://blog.danlew.net/2017/05/30/mutable-vals-in-kotlin/

          【讨论】:

            【解决方案8】:

            var 定义的变量是可变的(读写)

            val 定义的变量是不可变的(只读)

            Kotlin 可以删除 findViewById 并减少 android studio 中 setOnClickListener 的代码。如需完整参考:Kotlin awesome features

            可变变量的值可以随时改变,而不可变变量的值不能改变。

            我应该在哪里使用 var 以及在哪里使用 val ?

            在值经常变化的地方使用 var。例如在获取 android 设备的位置时

            var integerVariable : Int? = null
            

            在整个班级的价值没有变化的情况下使用 val。例如,您想以编程方式设置 textview 或按钮的文本。

            val stringVariables : String = "Button's Constant or final Text"
            

            【讨论】:

            • "Kotlin 可以删除 findViewById 并减少 android studio 中 setOnClickListener 的代码。完整参考:Kotlin awesome features" 这与提出的问题有什么关系?
            • val 变量不一定是不可变的。它们是最终的——只有引用是不可变的——但是如果存储在 val 中的对象是可变的,那么无论是通过 val 还是 var 分配的对象都是可变的。
            • 我没有看到引入两个新关键字的意义,虽然以前在 Java 中可以更好地理解它
            【解决方案9】:

            简单地认为 Val 就像 java 中的 final 变量

            【讨论】:

              【解决方案10】:

              您需要更改变量还是永久设置它?

              • 一个很好的例子,如果它类似于 val pi5places = 3.14159,您可以将其设置为 val。是否有可能现在或以后需要更改该变量,然后将其设置为 var。

              • 例如:汽车的颜色,可以是var colorCar = green。稍后您可以更改 colorCar = blue,而 val 则不能。

              • 此处关于 mutableimmutable 的回复很好,但如果这些术语不为人所知或刚开始学习如何编程,可能会很吓人。

              【讨论】:

                【解决方案11】:

                val 用于声明最终变量。 val变量的特征

                1. 必须初始化
                2. 值无法更改或重新分配

                var 是一个通用变量

                1. 我们可以稍后使用lateinit修饰符进行初始化

                  [lateinit 也用于全局变量 我们不能将它用于局部变量]

                2. 值可以更改或重新分配,但不能在全局范围内

                kotlin 中的val 类似于java 中的final 关键字

                【讨论】:

                  【解决方案12】:

                  val 属性类似于 Java 中的 final 属性。您只能为其分配一个值一次。当你第二次尝试重新分配一个值时,你会得到一个编译错误。而 var 属性是可变的,您可以根据需要随时重新分配它。

                  【讨论】:

                    【解决方案13】:

                    两者都是变量,唯一的区别是可变变量和不可变变量并没有什么区别。 var 是可变变量,val 是不可变的。在简单的语言中,var 可以在初始化后更改值 val 是常量,并且在初始化值后不能更改它的值。

                    【讨论】:

                      【解决方案14】:

                      valvar 都可用于声明变量(本地和类属性)。

                      局部变量

                      1. val 声明只读变量只能赋值一次,但不能重新赋值

                      例子:

                      val readonlyString = “hello”
                      readonlyString = “c u” // Not allowed for `val`
                      
                      1. var 声明 reassignable 变量,正如您在 Java 中所知道的那样(该关键字将在 Java 10 中引入,“local variable type inference”)。

                      例子:

                      var reasignableString = “hello”
                      reasignableString = “c u” // OK
                      

                      最好使用val。尽量避免var

                      类属性

                      这两个关键字也用于定义properties inside classes。例如,看看下面的data class

                      data class Person (val name: String, var age: Int)
                      

                      Person 包含两个字段,其中一个是只读字段 (name)。另一方面,age 可以在类实例化后通过提供的setter 重新分配。注意name 没有对应的setter 方法。

                      【讨论】:

                        【解决方案15】:

                        val(来自值): 不可变引用。不能用val 声明的变量 初始化后重新分配。它对应于 Java 中的 final 变量。

                        var(来自变量): 可变引用。这种变量的值是可以改变的。 此声明对应于常规(非最终)Java 变量。

                        【讨论】:

                          【解决方案16】:

                          valconstant一样的变量,本身不能改变,只能读取,但是可以修改val的属性; var 就像其他编程语言中的突变变量一样。

                          【讨论】:

                            【解决方案17】:
                            +----------------+-----------------------------+---------------------------+
                            |                |             val             |            var            |
                            +----------------+-----------------------------+---------------------------+
                            | Reference type | Immutable(once initialized  | Mutable(can able to change|
                            |                | can't be reassigned)        | value)                    |
                            +----------------+-----------------------------+---------------------------+
                            | Example        | val n = 20                  | var n = 20                |
                            +----------------+-----------------------------+---------------------------+
                            | In Java        | final int n = 20;           | int n = 20;               |
                            +----------------+-----------------------------+---------------------------+
                            

                            Reference

                            【讨论】:

                              【解决方案18】:

                              val是不可变的,最终的,第一个赋值的值不能改变。

                              val name:String = "andy"
                              
                              name = "thomas" //Error: Val cannot be reassigned
                              

                              var 是可变的、可重新分配的,您可以反复更改值。

                              val a:Int = 1
                              var b:Int = 1
                              println("${a + b}") // output 2
                              
                              b = 4
                              println("${a + b}") // output 5
                              

                              我认为最容易记住它的方法:

                              val = 变量最终

                              var = 可重新赋值的变量,或 val 的反义词。

                              【讨论】:

                              • 问题是关于两者之间的区别,而不是如何区分机器人。请通过下面的链接,这将帮助您发布好的答案stackoverflow.com/help/how-to-answer
                              • 所以你更喜欢相同的答案,尽管很多人一直在回答这个问题。对于一些刚接触 Kotlin 的人来说,val 和 var 听起来是一样的。所以你需要给他们一个如何区分它以及它们是什么的例子。但是,是的,我会接受你的建议。谢谢。
                              【解决方案19】:

                              两个变量都用作初始化

                              • val就像一个常量变量,可读,可以修改val的属性。

                              • var 就像一个可变变量。您可以随时更改该值。

                              【讨论】:

                                【解决方案20】:

                                Var 表示变量 - 如果您使用 'var' 存储任何对象,它可能会随时间改变。

                                例如:

                                fun main(args: Array<String>) {
                                    var a=12
                                    var b=13
                                    var c=12
                                    a=c+b **//new object 25**
                                    print(a)
                                }
                                

                                Val 表示-就像java中的'constant'。如果您使用'val'存储任何对象,它就无法更改及时。

                                例如:

                                fun main(args: Array<String>) {
                                    val a=12
                                    var b=13
                                    var c=12
                                    a=c+b **//You can't assign like that.it's an error.**
                                    print(a)
                                }
                                

                                【讨论】:

                                  【解决方案21】:

                                  VAR 用于创建那些其值将在您的应用程序中随时间变化的变量。它与swift的VAR相同,而VAL用于在您的应用程序中创建其值不会随时间变化的变量。它与swift的LET相同。

                                  【讨论】:

                                    【解决方案22】:

                                    val - 不可变(一旦初始化就不能重新赋值)

                                    var - 可变(可以改变值)

                                    例子

                                    在 Kotlin 中 - val n = 20 & var n = 20

                                    在 Java 中 - final int n = 20; & int n = 20;

                                    【讨论】:

                                      【解决方案23】:

                                      var 是一个可变变量,可以多次赋值 val 是不可变变量,只能初始化一次。

                                      【讨论】:

                                        【解决方案24】:

                                        在 Kotlin 中,我们使用 var 来声明一个变量。它是可变的。我们可以更改、重新分配变量。例如,

                                        fun main(args : Array<String>){
                                            var x = 10
                                            println(x)
                                        
                                            x = 100 // vars can reassign.
                                            println(x)
                                        }
                                        

                                        我们使用 val 来声明 常量。它们是不可变的无法更改,重新分配值。 val 类似于 java 中的 final 变量。例如,

                                        fun main(args : Array<String>){
                                            val y = 10
                                            println(y)
                                        
                                            y = 100 // vals can't reassign (COMPILE ERROR!).
                                            println(y)
                                        }
                                        

                                        【讨论】:

                                          【解决方案25】:

                                          我从de-compiling Kotlin to Java得到了确切的答案。

                                          如果你在 Kotlin 中这样做:

                                          data class UsingVarAndNoInit(var name: String)
                                          data class UsingValAndNoInit(val name: String)
                                          

                                          你会得到UsingVarAndNoInit

                                          package classesiiiandiiiobjects.dataiiiclasses.p04variiiandiiival;
                                          
                                          import kotlin.jvm.internal.Intrinsics;
                                          import org.jetbrains.annotations.NotNull;
                                          
                                          public final class UsingVarAndNoInit {
                                            @NotNull private String name;
                                          
                                            @NotNull
                                            public final String getName() {
                                              return this.name;
                                            }
                                          
                                            public final void setName(@NotNull String string) {
                                              Intrinsics.checkParameterIsNotNull((Object) string, (String) "<set-?>");
                                              this.name = string;
                                            }
                                          
                                            public UsingVarAndNoInit(@NotNull String name) {
                                              Intrinsics.checkParameterIsNotNull((Object) name, (String) "name");
                                              this.name = name;
                                            }
                                          
                                            @NotNull
                                            public final String component1() {
                                              return this.name;
                                            }
                                          
                                            @NotNull
                                            public final UsingVarAndNoInit copy(@NotNull String name) {
                                              Intrinsics.checkParameterIsNotNull((Object) name, (String) "name");
                                              return new UsingVarAndNoInit(name);
                                            }
                                          
                                            @NotNull
                                            public static /* bridge */ /* synthetic */ UsingVarAndNoInit copy$default(
                                                UsingVarAndNoInit usingVarAndNoInit, String string, int n, Object object) {
                                              if ((n & 1) != 0) {
                                                string = usingVarAndNoInit.name;
                                              }
                                              return usingVarAndNoInit.copy(string);
                                            }
                                          
                                            public String toString() {
                                              return "UsingVarAndNoInit(name=" + this.name + ")";
                                            }
                                          
                                            public int hashCode() {
                                              String string = this.name;
                                              return string != null ? string.hashCode() : 0;
                                            }
                                          
                                            public boolean equals(Object object) {
                                              block3:
                                              {
                                                block2:
                                                {
                                                  if (this == object) break block2;
                                                  if (!(object instanceof UsingVarAndNoInit)) break block3;
                                                  UsingVarAndNoInit usingVarAndNoInit = (UsingVarAndNoInit) object;
                                                  if (!Intrinsics.areEqual((Object) this.name, (Object) usingVarAndNoInit.name)) break block3;
                                                }
                                                return true;
                                              }
                                              return false;
                                            }
                                          }
                                          

                                          您还将获得 UsingValAndNoInit

                                          package classesiiiandiiiobjects.dataiiiclasses.p04variiiandiiival;
                                          
                                          import kotlin.jvm.internal.Intrinsics;
                                          import org.jetbrains.annotations.NotNull;
                                          
                                          public final class UsingValAndNoInit {
                                            @NotNull private final String name;
                                          
                                            @NotNull
                                            public final String getName() {
                                              return this.name;
                                            }
                                          
                                            public UsingValAndNoInit(@NotNull String name) {
                                              Intrinsics.checkParameterIsNotNull((Object) name, (String) "name");
                                              this.name = name;
                                            }
                                          
                                            @NotNull
                                            public final String component1() {
                                              return this.name;
                                            }
                                          
                                            @NotNull
                                            public final UsingValAndNoInit copy(@NotNull String name) {
                                              Intrinsics.checkParameterIsNotNull((Object) name, (String) "name");
                                              return new UsingValAndNoInit(name);
                                            }
                                          
                                            @NotNull
                                            public static /* bridge */ /* synthetic */ UsingValAndNoInit copy$default(
                                                UsingValAndNoInit usingValAndNoInit, String string, int n, Object object) {
                                              if ((n & 1) != 0) {
                                                string = usingValAndNoInit.name;
                                              }
                                              return usingValAndNoInit.copy(string);
                                            }
                                          
                                            public String toString() {
                                              return "UsingValAndNoInit(name=" + this.name + ")";
                                            }
                                          
                                            public int hashCode() {
                                              String string = this.name;
                                              return string != null ? string.hashCode() : 0;
                                            }
                                          
                                            public boolean equals(Object object) {
                                              block3:
                                              {
                                                block2:
                                                {
                                                  if (this == object) break block2;
                                                  if (!(object instanceof UsingValAndNoInit)) break block3;
                                                  UsingValAndNoInit usingValAndNoInit = (UsingValAndNoInit) object;
                                                  if (!Intrinsics.areEqual((Object) this.name, (Object) usingValAndNoInit.name)) break block3;
                                                }
                                                return true;
                                              }
                                              return false;
                                            }
                                          }
                                          

                                          这里还有更多例子:https://github.com/tomasbjerre/yet-another-kotlin-vs-java-comparison

                                          【讨论】:

                                            【解决方案26】:

                                            简而言之,val 变量是最终的(不可变的)或将来不会更改的常量值 和 var 变量(可变)将来可以更改。

                                            class DeliveryOrderEvent(val d : Delivery)
                                            // Only getter
                                            

                                            参见上面的代码。它是一个模型类,将用于数据传递。我在变量之前设置了val,因为这个变量是用来获取数据的。

                                            class DeliveryOrderEvent(var d : Delivery)
                                            
                                            // setter and getter is fine here. No error
                                            

                                            另外,如果你以后需要设置数据,你需要在变量之前使用var关键字,如果你只需要获取一次值,那么使用val关键字

                                            【讨论】:

                                              【解决方案27】:

                                              正常

                                              • Val 用于 static 字段,如 Java 中的 Static Keyword

                                              • 类似于 Java 中的 Static/ 与 kotlin 中的相同

                                              • Var 表示 Kotlin 中的变量字段,您可以更改它。

                                              • 大多数情况下,Static 用于将值一次保存在静态内存中,

                                              例子:

                                               if you assign
                                              
                                               val a=1
                                               a=3  You can not change it 
                                              
                                              • 你不能改变,这是最终值和静态

                                                var b=2

                                                b=4你可以改

                                              【讨论】:

                                                【解决方案28】:

                                                让我们试试这个方法。

                                                Val is a Immutable constant 
                                                    val change="Unchange" println(change)
                                                    //It will throw error because val is constant variable
                                                    // change="Change" 
                                                    // println(change)
                                                Var is a Mutable constant
                                                    var name: String="Dummy"
                                                    println(name)
                                                    name="Funny"
                                                    println(name)
                                                

                                                【讨论】:

                                                  【解决方案29】:

                                                  val 变量的值只能分配一次。

                                                  val address = Address("Bangalore","India")
                                                  address = Address("Delhi","India") // Error, Reassigning is not possible with val
                                                  

                                                  虽然你不能重新赋值,但你当然可以修改对象的属性。

                                                  //Given that city and country are not val
                                                  address.setCity("Delhi") 
                                                  address.setCountry("India")
                                                  

                                                  这意味着您无法更改变量指向的对象引用,但可以更改该变量的基础属性。

                                                  可以根据需要多次重新分配 var 变量的值。

                                                  var address = Address("Bangalore","India")
                                                  address = Address("Delhi","India") // No Error , Reassigning possible.
                                                  

                                                  显然,它的底层属性可以更改,只要它们没有声明为 val。

                                                  //Given that city and country are not val
                                                  address.setCity("Delhi")
                                                  address.setCountry("India")
                                                  

                                                  【讨论】:

                                                    【解决方案30】:

                                                    基本上

                                                    • var = 变量,所以它可以改变
                                                    • val = ,所以不能改变。

                                                    【讨论】:

                                                      猜你喜欢
                                                      • 1970-01-01
                                                      • 2019-09-21
                                                      • 2018-12-07
                                                      • 1970-01-01
                                                      • 1970-01-01
                                                      • 1970-01-01
                                                      • 2016-10-02
                                                      • 1970-01-01
                                                      • 1970-01-01
                                                      相关资源
                                                      最近更新 更多