惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

B
Blog RSS Feed
J
Java Code Geeks
H
Help Net Security
Google DeepMind News
Google DeepMind News
博客园 - 司徒正美
Microsoft Security Blog
Microsoft Security Blog
宝玉的分享
宝玉的分享
Stack Overflow Blog
Stack Overflow Blog
D
DataBreaches.Net
The GitHub Blog
The GitHub Blog
S
SegmentFault 最新的问题
U
Unit 42
博客园 - 三生石上(FineUI控件)
Last Week in AI
Last Week in AI
M
MIT News - Artificial intelligence
WordPress大学
WordPress大学
小众软件
小众软件
博客园 - 叶小钗
D
Docker
量子位
P
Proofpoint News Feed
博客园_首页
T
Tailwind CSS Blog
F
Fortinet All Blogs

Kotlin : A concise multiplatform language developed by JetBrains | The JetBrains Blog

Kotlin 2.4.20 Released - The JetBrains Blog Kotlin Toolchain 0.12: Multiplatform Library Publishing, Wasm Apps, and More - The JetBrains Blog Compose Multiplatform 1.12.0 Released - The JetBrains Blog Signatures, be true: domain errors and functional handling in Kotlin - The JetBrains Blog Klibs.io Grows to 4,200+ KMP Projects With Smarter Discovery and New AI Integrations - The JetBrains Blog Exploring Compose HTML for Server Side Rendering - The JetBrains Blog Programming Language Migration 2025: Why Developers Switch Kodee’s Kotlin Roundup: Birthday Wishes, Shipaton 2026, and the New Kotlin AI Benchmark - The JetBrains Blog Know Kotlin? Ship It Everywhere and Win at Shipaton 2026 - The JetBrains Blog Qodana 2026.2: More Security, Better Coverage, Less Configuration - The JetBrains Blog Secure Your APIs: OAuth2 and JWT for Beginners - The JetBrains Blog KotlinLLM is Going Open Source  - The JetBrains Blog Kotlin Turns 15: Celebrate the Kotlin Effect - The JetBrains Blog The History of Kodee, Kotlin’s Mascot - The JetBrains Blog Introducing the Kotlin Benchmark for AI Coding Agents - The JetBrains Blog In Conversation With the Golden Kodee Winners - The JetBrains Blog Kotlin Comes to BlueJ - The JetBrains Blog Kodee’s Kotlin Roundup: Kotlin Turns 15, Kotlin 2.4.0, and the Kotlin Toolchain - The JetBrains Blog Kotlin Notebook Sunset - The JetBrains Blog Kotlin Toolchain 0.11: The Next Step for Amper - The JetBrains Blog Kotlin 2.4.0 Released | The Kotlin Blog Koog 1.0 Is Out: Stable Core, Better Interop, and Multiplatform Observability | The JetBrains AI Blog KotlinConf’26 Keynote Highlights: Advances in Language Design, Tooling, AI-Driven Workflows, and Multiplatform Development | The Kotlin Blog Introducing a Security Support Policy for the Kotlin Standard Library | The Kotlin Blog Official Kotlin Support for Visual Studio Code Is Now Available in Alpha | The Kotlin Blog Built for Productivity: What the Data Finally Shows About Kotlin | The Kotlin Blog A New Default Project Structure for Kotlin Multiplatform | The Kotlin Blog Help Shape the Future of Kotlin in the Age of AI | The Kotlin Blog Compose Multiplatform 1.11.0 Is Now Available | The Kotlin Blog JetBrains 推出的 Kotlin 专业认证现已登陆 LinkedIn Learning | The Kotlin Blog
The Road to Name-Based Destructuring | The Kotlin Blog
Alejandro Serrano Mena · 2026-05-13 · via Kotlin : A concise multiplatform language developed by JetBrains | The JetBrains Blog
Kotlin logo

A concise multiplatform language developed by JetBrains

News Tutorials

The Road to Name-Based Destructuring

TL;DR

  • New “val inside parentheses” syntax is being introduced to allow for name-based destructuring. Additionally, new syntax with square brackets is being introduced for positional destructuring.
    • Both are currently Experimental (enabled using the -Xname-based-destructuring=only-syntax compiler argument) and will become Stable in a future release.
  • In the distant future, the behavior of the “val outside parentheses” syntax for destructuring will change from being position-based to name-based.
    • There will be a long migration period before the default changes, and tooling is already in place to help with migration.
    • You can already make the switch to the new behavior (-Xname-based-destructuring=complete), but note its Experimental status.
  • The compiler ships with migration helpers that will be enabled by default for a few versions, and it will be some time before the new behavior becomes the default.
    • You can enable these helpers now by using -Xname-based-destructuring=name-mismatch.

Kotlin is changing, with names set to become central in destructuring. In the future, val (name, age) = person will extract the name and age properties from the person value, regardless of the way and order in which they were defined. This marks a change from the current approach to destructuring, in which the position is the key element. This blog post explains the reasoning behind this change, the migration strategy, and how Kotlin’s tooling supports it.

Why destructure by name instead of position?

Destructuring is most commonly used to access properties from data classes. For example, we can define a Person class as follows:

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

Then we can extract several of the primary properties in a single go. This is what we call destructuring the value into its components.

fun isValidPerson(p: Person) {
  val (name, age) = p
  return name.isNotEmpty() && age >= 0
}

Currently, destructuring is done by position. The variables we introduce in a destructuring declaration often follow the names of the properties in the data class, but there’s no such requirement in the language.

// this is exactly the same function as above
fun isValidPerson(p: Person) {
  val (foo, bar) = p
  return foo.isNotEmpty() && bar >= 0
}

This lack of connection can cause problems, as it is very easy to inadvertently swap the order of two properties. This mistake may be caught later because of non-matching types, but it appears far from the actual origin.

The way in which components relate to primary properties also hinders refactoring. For example, we cannot move the age property to be computed and still retain the nice data class syntax. Imagine we make the following change:

data class Person(val name: String, val birthdate: Date) {
  val age = (Date.now() - birthdate).years
}

Now every destructuring declaration suddenly changes from age to birthdate! To be clear, source compatibility is still possible, but you need to do a lot more work.

The current approach to destructuring is also at odds with abstraction. If we turned Person into an interface, previous instances of destructuring would no longer be valid. We could work around this by introducing our own component functions, but this is usually seen as advanced. As a result, most interfaces do not provide such facilities.

interface Person {
  val name: String
  val age: Int

  operator fun component1(): String = name
  operator fun component2(): Int    = age
}

These problems go away if destructuring depends on names instead of positions. It doesn’t matter if you rearrange the order, change a computed property into a primary one or vice versa, or define a property in a class, interface, or object. The property’s name is a stable characteristic, which means that the source does not require any changes.

The new syntax

You can enable the new syntax by passing -Xname-based-destructuring=only-syntax as a compiler argument.

Without further ado, let’s look at the new syntax, which uses names for destructuring. Instead of a single val outside of the parentheses, you use val for each property inside the parentheses.

fun isValidPerson(p: Person): Boolean {
  (val name, val age) = p
  return name.isNotEmpty() && age >= 0
}

As expected, the order in which we write val name and val age in the example above doesn’t matter. This new syntax also supports renaming for cases in which the new variable you want to define is not the same as the property you want to access.

fun isValidPerson(p: Person): Boolean {
  (val age, val theName = name) = p
  return theName.isNotEmpty() && age >= 0
}

Destructuring based on position is still important for a few use cases. Pairs and triples, for example, don’t have names for their components at a conceptual level, and there’s no intention to require littering code that uses them with first and second. Position-based destructuring can also be used for collections, and in that case, there are no available properties. The new syntax for position-based destructuring uses square brackets – mirroring the syntax of upcoming collection literals. You can choose whether to put val inside or outside the brackets.

fun isZero(point: Pair<Int, Int>): Boolean {
  val [x, y] = point      // one way
  [val x, val y] = point  // or another
  return x == 0 && y == 0
}

All of this new syntax is available anywhere you can destructure, including lambda expressions and loops.

// suggested new syntax for iterating through a map
for ([key, value] in map) {
  // work with each entry
}

person?.let { (val name, val years = age) -> "$name is $years years old" }

To reiterate: This is all new syntax. As of version 2.3.20, the compiler knows what it means, and we intend to keep this syntax once the feature reaches Stable status.

Repurposing parentheses

At some point in the future, we intend for all destructuring using parentheses to be name-based. You can actually experience this future now by using the -Xname-based-destructuring=complete compiler argument.

If you already have a project, though, making the switch could have a major impact. The most visible issue would be if destructuring stops working, and the code needs to be updated. A more dangerous one would be destructuring declarations that remain valid but change the meaning.

For that reason, the compiler ships a migration helper under the -Xname-based-destructuring=name-mismatch compiler argument. When enabled, the compiler gives a warning in cases where the behavior is inconsistent between position-based and name-based destructuring or where the code won’t be accepted once destructuring with parentheses is no longer positional.

// accepted by both with the same behavior 
val (name, age) = person

// warning: accepted by both, but the behavior changes
val (age, name) = person

// warning: accepted only by position-based destructuring
val (personName, personAge) = person
// the IDE suggests potential fixes
// - renaming: (val personName = name, val personAge = age) = person
// - square brackets: val [personName, personAge] = person

The future

As hinted in this post, there will be ample time to migrate to the new name-based destructuring. Our current timeline looks as follows:

  • As of version 2.3.20, name-based destructuring is Experimental, meaning that you need a special compiler argument to use it.
    • Support in IntelliJ IDEA may be lacking, especially for migration.
  • With version 2.5.0 (at the end of 2026), the feature will become Stable.
    • The new syntax will be available without additional configuration.
    • The compiler will start reporting migration hints, and IntelliJ IDEA will include inspections and quick-fixes to help with the process.
    • This stage roughly corresponds to name-mismatch in compiler arguments, although we may make some adjustments to reporting depending on user feedback.
  • By version 2.7.0 (at the end of 2027), destructuring with parentheses will be name-based.
    • You can migrate to this stage earlier by using complete in compiler arguments.

This is a big change, and we don’t want to rush it. If at any point during 2027 it becomes clear that the ecosystem is not ready, we may postpone the change until another major version.

At no point are we deprecating the generation of component functions for data classes. Data classes will still generate the same bytecode – name-based destructuring is a feature for use sites. However, we plan to introduce multi-field value classes without component functions. That means that destructuring for value classes will only be name-based.

References

Subscribe to Kotlin Blog updates

Discover more