Kotlin编译器如何知道Val应该是属性还是功能

发布于 2025-02-12 08:52:45 字数 242 浏览 2 评论 0原文

以下Kotlin代码 val namehash get()= name.hashcode() 可以按照以下方式将其编译到Java中

public final int getNameHash() {
    return name.hashCode();
}

,而属性命名为“失望”。 但是,当Val更改为VAR时,编译器说“必须初始化属性” var和val之间的较深差异是什么?

The following kotlin code
val nameHash get() = name.hashCode()
can be compiled into java as follows

public final int getNameHash() {
    return name.hashCode();
}

and the property nameHash disapears.
However when the val is changed to var, the compiler says "Property must be initialized"
What is the deeper difference between var and val?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

抠脚大汉 2025-02-19 08:52:45

Kotlin编译器如何知道Val应该是属性还是功能

Kotlin编译器如何就 kotlin 语言而言, ,val表示属性,表示属性,从不起作用。但是,这两个属性声明之间存在

val nameHash get() = name.hashCode()
var nameHash get() = name.hashCode()

那是第一个属性没有 backing字段。例如,具有备份字段的属性必须以一种或另一种方式初始化:

var nameHash = 0 // for example
    get() = name.hashCode()

这就是为什么使用var没有编译的代码的原因。

如果您要求为Kotlin属性生成备份字段时的情况,则它们在 spec

但是,仅为属性创建衬背
以下情况

  • 属性没有自定义登录;
  • 属性具有默认访问者;
  • 属性具有自定义访问者,它使用字段属性;
  • 可变的属性具有自定义Getter或Setter,但不是两者。

在这些情况下,您的属性需要备用字段。您的var namehash满足了最后一个情况,因为它是“可变属性”。如果您使用Val,则不再是可变属性,并且不满足任何情况。

直觉上,没有设置器的可变属性需要一个备用字段,因为必须能够设置该属性。当没有设置器时,如何设置它?好吧,Kotlin编译器通过生成衬板来解决问题,而只是设置了背景字段。

How does kotlin compiler know whether a val should be a property or a function

As far as the Kotlin language is concerned, val denotes properties, never functions. However, there is a difference between these two property declarations:

val nameHash get() = name.hashCode()
var nameHash get() = name.hashCode()

And that is that the first property does not have a backing field. Properties with backing fields must be initialised one way or another, for example:

var nameHash = 0 // for example
    get() = name.hashCode()

And this is why your code with var didn't compile.

If you are asking for the situations when a backing field is generated for a Kotlin property, they are listed in the spec:

However, the backing field is created for a property only in the
following cases

  • A property has no custom accessors;
  • A property has a default accessor;
  • A property has a custom accessor, and it uses field property;
  • A mutable property has a custom getter or setter, but not both.

These are the cases where your property needs a backing field. Your var nameHash satisfies that last case, because it is a "mutable property". If you use val instead, it is not a mutable property anymore and doesn't satisfy any of those cases.

Intuitively, a mutable property without setter needs a backing field because one must need to be able to set the property. How can you set it when it has no setter? Well, the Kotlin compiler solves the problem by generating a backing field and just sets the backing field instead.

冷清清 2025-02-19 08:52:45

属性是函数set()& get()。仅读取属性仅实现get()函数,但是它仍然是一个函数,因此每次调用属性中写入的所有内容都将执行。

在Kotlin中,关键字:val与仅读取属性相同,这意味着仅实现get()函数是必需的。当您放置var关键字时,编译器期望您实现这两个get()& set()函数。

因此,在此编译错误是因为您的属性缺少set()通常需要存储一个值所需的功能(或如编译器所说:必须初始化)。

Property is a functions set() & get(). Read-only properties implement only the get() function, but still, it's a function, so everything written in the property will be executed every time it's called.

In Kotlin, keywords: val is the same as the read-only property, meaning it's required to implement only get() function. When you put var keyword, compiler expects you to implement both get() & set() functions.

So, compile error there because your property missing set() function that is usually needed to store a value (or as the compiler says: must be initialized).

鹿港巷口少年归 2025-02-19 08:52:45

在这种情况下,错误消息有点令人困惑。 valvar之间的区别在于val意味着有一个getter,而var表示有一个getter和二传手。要修复您的代码,您需要为设置器添加实现:

var nameHash
    get() = name.hashCode()
    set(hash: Int) { ... }

尽管在这种情况下,我认为这没有太多意义。我们无法设置name的哈希代码值。

The error message is a little confusing in this case. The difference between val and var is that val means there is a getter while var means there is a getter and a setter. To fix your code you need to add an implementation for the setter:

var nameHash
    get() = name.hashCode()
    set(hash: Int) { ... }

Although, in this case I don't think it makes too much sense. We can't set the hash code value of the name.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文