"const"和"val"有什么区别?

Mat*_*any 231 constants kotlin

我最近读过这个const关键字,我很困惑!我找不到它和const关键字之间的任何区别,我的意思是我们可以使用它们来制作一个不可变的变量,还有什么我不知道的吗?

Luk*_*itz 323

consts是编译时常量.这意味着它们的值必须在编译期间分配,与vals 不同,它可以在运行时完成.

这意味着,consts永远不能分配给函数或任何类构造函数,而只能分配给String或原语.

例如:

const val foo = complexFunctionCall()   //Not okay
val fooVal = complexFunctionCall()  //Okay

const val bar = "Hello world"           //Also okay
Run Code Online (Sandbox Code Playgroud)

  • 这引出了另一个问题:为什么Kotlin需要`const val`而不仅仅是`const`?在我看来,`val`关键字在这种情况下完全是多余的,因为`const var`在它的表面上是荒谬的. (93认同)
  • @EricLloyd使用`const val`,`const`是`val`而不是关键字的修饰符.修饰符>关键字.这个相同设计的更多例子是`annotation/enum/data class`,`private val`,`inline fun`等. (15认同)
  • @MathewHany,至少不是字节码,请参阅:http://stackoverflow.com/questions/37482378/static-data-in-kotlin/37485356#37485356 (5认同)
  • 我认为`const`值将在编译期间完全内联. (4认同)
  • 这样的事情:`const val foo ="Hello world"`和`val bar ="Hello world"`?它们是一样的吗? (3认同)
  • 那为什么要分化呢?为什么编译器不能确定一个值是否为const并在编译时无法计算它的值? (2认同)
  • @FlorianWalther是的,这是个主意-我通常使用const表示真正的不可变值-HTTP动词,Pi的值等。如果它是可变的甚至是可配置的值,则const不是回答。 (2认同)
  • @Dainius,我猜这是出于必要而完成的,因为“const”是一个软关键字。您可以将其用作变量或函数名称。如果你可以写“const”而不写“val”,那么它一定是一个硬关键字。 (2认同)

EPa*_*onU 30

只是为了增加Luka的答案:

编译时常数

编译时已知的值的属性可以使用const修饰符标记为编译时常量.这些属性需要满足以下要求:

  • 顶级或对象的成员
  • 使用String类型或基本类型初始化
  • 没有自定义的吸气剂

这些属性可用于注释.

资料来源:官方文件


小智 18

const kotlin 到 Java

const val Car_1 = "BUGATTI" // final static String Car_1 = "BUGATTI";
Run Code Online (Sandbox Code Playgroud)

val kotlin 到 Java

val Car_1 = "BUGATTI"   // final String Car_1 = "BUGATTI";
Run Code Online (Sandbox Code Playgroud)

用简单的语言

  1. const 变量的值在编译时是已知的。
  2. val 的值用于在运行时定义常量。

示例 1-

const val Car_1 = "BUGATTI" ?  
val Car_2 = getCar() ?    
const val Car_3 = getCar() ? 

//Because the function will not get executed at the compile time so it will through error

fun getCar(): String {
    return "BUGATTI"
}
Run Code Online (Sandbox Code Playgroud)

这是因为 getCar() 在运行时被评估并将值分配给 Car。

此外 -

  1. val是只读的意味着在运行时已知的不可变
  2. var是可变的,在运行时已知
  3. const是不可变的和在编译时已知的变量


Jin*_*ang 15

您可以将Kotlin转换为Java.然后你可以看到const有一个比val更多的静态修饰符.像这样的简单代码.

科特林:

const val str = "hello"
class SimplePerson(val name: String, var age: Int)
Run Code Online (Sandbox Code Playgroud)

致Java(部分):

@NotNull
public static final String str = "hello";

public final class SimplePerson {
   @NotNull
   private final String name;
   private int age;

   @NotNull
   public final String getName() {
      return this.name;
   }

   public final int getAge() {
      return this.age;
   }

   public final void setAge(int var1) {
      this.age = var1;
   }

   public SimplePerson(@NotNull String name, int age) {
      Intrinsics.checkParameterIsNotNull(name, "name");
      super();
      this.name = name;
      this.age = age;
   }
}
Run Code Online (Sandbox Code Playgroud)

  • 有人可以在评论中说明为什么这个答案被低估了吗? (3认同)
  • @JamesJordanTaylor 我投了赞成票。但我认为这是因为有些人没有仔细阅读它,乍一看这个答案似乎在谈论如何从java转换为kotlin,这将是题外话。 (3认同)
  • @DYS:我认为它将删除“静态”,并且只是 public final String str =“hello”; (3认同)
  • 如果删除 `const` 会产生不同的 Java 文件吗? (2认同)

Aja*_*rma 15

在科特林,const并且val两者代表的不变性和只读值,并作为final在Java关键字。

val关键字必须用于声明运行时值,const关键字必须用于声明编译时值。

请记住, const 必须仅用于原始数据类型,而不用于函数和构造函数。

例子 -

const val fun1 = anyFunctionOrConstructor() // it is not fine
val fun2 = anyFunctionOrConstructor() // it is perfectly fine      
const val aa = "My String" // it is perfectly fine
Run Code Online (Sandbox Code Playgroud)


Kif*_*lah 12

这两个valconst是不可变的。

const用于声明编译时常量,而val用于声明运行时常量。

const val VENDOR_NAME = "Kifayat Pashteen"  // Assignment done at compile-time

val PICon = getIP()  // Assignment done at run-time
Run Code Online (Sandbox Code Playgroud)

  • @什么什么什么是的。代码在发送执行之前进行编译。代码执行的时间点本质上称为运行时执行。 (2认同)

小智 12

因为我读了很多,“val”意味着不可变:这绝对不是这种情况,只需看这个例子:

class Test {
    var x: Int = 2
    val y
        get() = x
}

fun main(args: Array<String>) {
    val test = Test()
    println("test.y = ${test.y}") // prints 2
    test.x = 4
    println("test.y = ${test.y}") // prints 4
}
Run Code Online (Sandbox Code Playgroud)

遗憾的是,真正的不变性目前只能通过 const 来实现——但这只能在编译时实现。在运行时你无法创建真正的不变性。

val 只是意味着“只读”,您不能直接更改此变量,只能间接更改,就像我在上面的示例中所示的那样。


ARG*_*Geo 7

瓦尔

与Kotlin关键字相比,Kotlinval关键字用于只读var属性。read-only属性的另一个名称是immutable

科特林代码:

val variation: Long = 100L
Run Code Online (Sandbox Code Playgroud)

Java 等效项如下所示:

final Long variation = 100L;
Run Code Online (Sandbox Code Playgroud)


常量值

我们const也使用关键字来表示不可变属性。const用于编译时已知的属性。这就是区别。考虑到const财产必须申报globally

Kotlin 代码(在操场上):

const val WEBSITE_NAME: String = "Google"

fun main() {    
    println(WEBSITE_NAME)
}
Run Code Online (Sandbox Code Playgroud)

Java代码(在操场上):

class Playground {

    final static String WEBSITE_NAME = "Google";

    public static void main(String[ ] args) {
        System.out.println(WEBSITE_NAME);
    }
}
Run Code Online (Sandbox Code Playgroud)


Rah*_*rma 7

对于那些正在寻找val和之间哪个更合适或更有效的人const

对于 String 或任何原始数据类型,const val建议使用而不是val. 因为val将在运行时知道,所以当您的应用程序运行时它将处理所有值。另一方面,const val将在编译时更早地执行此操作。因此,性能方面const val会给出更好的结果。


Ami*_*har 7

让我们通过一个例子来学习这一点。

object Constants {

    val NAME = "Amit"

}
Run Code Online (Sandbox Code Playgroud)

注意:我们没有使用const.

并且,我们按如下方式访问它NAME

fun testValWithoutConst() {
    val name = Constants.NAME
}
Run Code Online (Sandbox Code Playgroud)

现在,我们需要反编译这段代码。为此,我们必须将此 Kotlin 源文件转换为 Java 源文件。

我们将得到以下输出:

public final void testValWithoutConst() {
  String name = Constants.INSTANCE.getNAME();
}
Run Code Online (Sandbox Code Playgroud)

输出如预期。

上面的例子没有关键字const。现在,让我们使用const关键字。

为此,我们将Constants在 Kotlin 中修改我们的对象类,如下所示:

object Constants {

    const val NAME = "Amit"

}
Run Code Online (Sandbox Code Playgroud)

注意:我们正在使用const.

并且,我们按如下方式访问它NAME

fun testValWithConst() {
    val name = Constants.NAME
}
Run Code Online (Sandbox Code Playgroud)

现在,当我们反编译这段代码时,我们将得到以下输出:

public final void testValWithConst() {
  String name = "Amit";
}
Run Code Online (Sandbox Code Playgroud)

在这里,我们可以看到该变量NAME已被其值替换,即Amit

由于该值已被内联,因此在运行时访问该变量不会产生任何开销。因此,它将带来更好的应用程序性能。

这就是在Kotlin中使用的优点const

参考我的博客:Advantage of using const in Kotlin