在Kotlin中var和val的区别是什么?

在Kotlin中varval之间的区别是什么?

我已经通过了这个链接:

KotlinLang: Properties and Fields

如本连结所述:

只读属性声明的完整语法不同于 可变1有两种方式:它以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之间的确切区别是什么?

为什么我们两者都需要?

这是Kotlin中的变量,与Java的差异:'var'和& # 39;val # 39; ?不是复制品,因为我问的是与文档中特定示例相关的疑问,而不仅仅是一般的疑问。

179430 次浏览

在你的代码中,result没有改变,它的var属性正在改变。参考以下评论:

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变量赋值,但可以改变它的属性。

var是一个像任何其他语言一样的变量。 如:< / p >

var price: Double
另一方面,val提供了引用功能。 如。< / p >
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

如果使用val声明变量,则变量为只读。我们不能改变它的值。它就像Java最后变量。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进行初始化。

你可以简单地把它想成:

var用于setter(值会改变)。

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

< p >简单, var(可变的)和val(在Java中不可变的值(最终修饰符))

var x:Int=3
x *= x


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

在Kotlin中,val是immutable, var是mutable

valvar都用于声明变量。

var类似于一般变量,它被称为芬兰湾的科特林中的可变变量,可以被多次赋值。

瓦尔类似于最后变量,它在芬兰湾的科特林中是不可变的,只能初始化一次。

有关valvar的更多信息,请参见下面的链接

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

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

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

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

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

我应该在哪里使用var和where val

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

var integerVariable : Int? = null

在整个类的值没有变化时使用val。例如,你想通过编程方式设置文本视图或按钮的文本。

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

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

你需要改变一个变量还是永久设置它?

  • 一个很好的例子,如果它是val pi5places = 3.14159,你可以将它设置为val。是否有可能你现在或以后需要改变这个变量,那么你会把它设为var。

  • 例如:汽车的颜色,可以是var colorCar = green。之后你可以改变这个colorCar = blue,而作为一个val,你不能。

  • 这里关于mutableimmutable的回答很好,但如果这些术语不是很熟悉或刚刚开始学习如何编程,可能会很可怕。

val用于声明final变量。val变量的特征

  1. 必须初始化
  2. 值不能更改或重新分配 李enter image description here < / >

var是一个通用变量

  1. 稍后可以使用lateinit修饰符初始化

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

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

enter image description here

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

瓦尔属性类似于Java中的final属性。您只允许为它分配一个值一次。当你第二次尝试给它重新赋值时,你会得到一个编译错误。而var属性是可变的,你可以在你想要的任何时候自由地重新分配它。

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

valvar都可以用于声明变量(局部和类属性)。

局部变量:

  1. val声明了只能赋值一次的只读变量,但是不能重新分配. 0声明了只能赋值一次的只读变量。

例子:

val readonlyString = “hello”
readonlyString = “c u” // Not allowed for `val`
  1. var声明了你从Java中知道的reassignable变量(关键字将在Java 10中引入,“局部变量类型推断”)。

例子:

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

最好使用val。尽量避免使用var !

类属性:

为了定义类中的属性,也使用了这两个关键字。作为一个例子,看一下下面的data class:

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

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

val (from value): 不可变的参考。用val声明的变量不能是 在初始化后重新赋值。它对应于Java中的final变量 var (from变量): 可变参考。这样一个变量的值是可以改变的。 此声明对应于一个常规(非final) Java变量

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

+----------------+-----------------------------+---------------------------+
|                |             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 .

瓦尔是不可变的,final,第一个赋值不能改变。

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 =变量final

Var =变量可重赋,或val的相反。

两个变量都用于初始化

  • val就像一个常量变量,它是可读的,并且val的属性可以被修改。

  • Var就像一个可变变量。你可以在任何时候改变这个值。

Var表示__abc1 -如果你使用“var”存储任何对象,它可能会随着时间发生变化。

例如:

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

瓦尔表示__abc1 -它就像java中的“不变”。如果你使用'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)
}

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

val -不可变(初始化后不能重新赋值)

var - Mutable(可以改变值)

例子

in Kotlin - val n = 20 &Var n = 20

在Java - final int n = 20;,Int n = 20;

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

在Kotlin中,我们使用var来声明变量。它是可变的。我们可以 change, 重新分配变量。的例子,

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)
}

我从将Kotlin反编译为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

简而言之,瓦尔变量是final(不可变)或将来不会改变的常量值 而且 Var 变量(可变)可以在未来改变。

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

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

class DeliveryOrderEvent(var d : Delivery)


// setter and getter is fine here. No error

同样,如果你以后需要设置数据,你需要在变量之前使用var关键字,如果你只需要获得一次值,那么使用瓦尔关键字

正常的

  • 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你可以改变它

我们试试这种方法。

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)

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")

基本上

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

在Kotlin中,val是一个只读属性,只能通过getter访问它。val是不可变的。

val示例:

val piNumber: Double = 3.1415926
get() = field

然而,var是一个的读写属性,因此它不仅可以由getter访问,还可以由setter访问。var是可变的。

var示例:

var gravity: Double = 9.8
get() = field
set(value) {
field = value
}

如果你试图改变一个不可变的val, IDE会显示错误:

fun main() {
piNumber = 3.14          // ERROR
println(piNumber)
}


// RESULT:   Val cannot be reassigned

但是可变的var可以被改变:

fun main() {
gravity = 0.0
println(gravity)
}


// RESULT:   0.0

< >强薇尔: 必须添加或初始化值,但不能更改。 var: 它的变量可以在代码中的任何一行中更改

两种方法创建变量在KOTLIN VAL和VAR

1.瓦尔存储常量值。也被称为最后一个变量

2.VAR存储可变值

例如,点击这里

瓦尔是不可变的,它的属性被设置为运行时,但是你可以使用常量修饰符使它成为编译时间常数kotlin中的Val与java中的final相同。

Var是可变的,它的类型在编译时处被标识。

在Kotlin中,我们有两种类型的变量:var或val 可在初始化后更新的可变引用(读写)。var 关键字用于定义Kotlin中的变量。它相当于一个普通的(非final) Java变量。如果我们的变量在某个时候需要改变,我们应该这样做 使用var关键字声明它。让我们看一个变量的例子 声明:< / p >
 fun main(args: Array<String>) {
var fruit:String = "orange"  // 1
fruit = "banana"             // 2
}
在kotlin中,我们可以用两种类型声明变量:valvarval不能重新赋值,它作为最终变量
val x = 2
x=3 // cannot be reassigned

另一方面,var可以被重新赋值它是可变的

var x = 2
x=3 // can be reassigned

val比作final是错误的!

__abc0是可变的, __abc1是只读;是的,val不能像Java中的final变量一样被重新赋值,但它们可以随着时间的推移返回不同的值,所以说它们是不可变的是错误的;

考虑以下几点

var a = 10
a = 11 //Works as expected
val b = 10
b = 11 //Cannot Reassign, as expected

真是太好了!

现在考虑下面的__abc

val d
get() = System.currentTimeMillis()


println(d)
//Wait a millisecond
println(d) //Surprise!, the value of d will be different both times

因此,vars可以对应于Java中的非最终变量,但val也不是最终变量;

虽然在kotlin中有const可以像final一样,因为它们是编译时常量,没有自定义getter,但它们只适用于原语

var就像一个通用变量,可以被多次赋值,在Kotlin中被称为可变变量。而瓦尔是一个常量变量,不能被赋值多次,只能被初始化一次,在Kotlin中被称为不可变变量。

< >强薇尔: 赋值一次(只读)

< >强Var: 可变的< / p > < p >的例子: 定义一个变量来存储userId值:

val userId = 1

如果我们试图改变变量userId,你会得到错误消息

userId = 2
error: val cannot be reassigned // Error message!

让我们创建一个新变量来存储用户名:

var userName = "Nav"

如果你想重新分配userName的值,你可以很容易地做到这一点,因为var是可变的

userName = "Van"

现在userName的值是&;Van"。

更多信息请访问: https://medium.com/techmacademy/kotlin-101-val-vs-var-behind-the-scenes-65d96c6608bf < / p >

虽然我迟到了,但有一点我还没发现。你可以使用valwhen表达式中赋值一个局部变量,但是尝试使用var会产生编译器错误:

sealed class Token {
data class StringToken(val value: String) : Token()
data class BoolToken(val value: Boolean) : Token()
}


fun getToken() : Token = Token.BoolToken(true)


val output = when (val token = getToken()) {
is Token.StringToken -> token.value
is Token.BoolToken -> token.value.toString()
}

这允许您访问右边表达式中正确的类型推断值。

Var是一个可变变量。它是一个可以更改为另一个值的变量。这类似于在Java中声明一个变量。

瓦尔是一个只读的东西。它类似于java中的最后。val在创建时必须初始化。这是因为它在创建之后就不能更改了。

var test1Var = "Hello"
println(test1Var)
test1Var = "GoodBye"
println(test1Var)
val test2Val = "FinalTestForVal";
println(test2Val);
我们使用var来声明变量和 我们使用val来创建常量,在java中,它的前面是保留字final