You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Dart中是否存在Kotlin with(receiver)函数的等价实现?

Dart中是否有与Kotlin with 函数等价的实现?

先看一下Kotlin中的示例场景:

定义一个User类:

class User {
    lateinit var firstname: String
    lateinit var lastname: String
    lateinit var age: String
}

常规初始化使用:

fun main() {
    val user = User()
    user.firstname = "firstname"
    user.lastname = "lastname"
    user.age = "25";
    println("Hello, ${user.firstname} ${user.lastname}, you are ${user.age} !")
}

输出:> Hello, firstname lastname, you are 25 !

Kotlin的with关键字可以避免重复写对象名,简化代码:

fun main() {
    val user = User()
    with (user) {
        firstname = "firstname"
        lastname = "lastname"
        age = "25";
        println("Hello, $firstname $lastname, you are $age !")
    }
}

那么Dart中有没有类似的实现?


Dart本身没有和Kotlin with(receiver: T, block: T.() -> R) 完全一致的内置函数,但可以通过以下几种方式实现类似效果:

1. 级联运算符(..)

这是Dart官方推荐的替代方案,能直接对对象进行链式操作,减少重复书写对象名的冗余:

先定义Dart版的User类:

class User {
  late String firstname;
  late String lastname;
  late String age;
}

使用级联运算符初始化并使用:

void main() {
  final user = User()
    ..firstname = "firstname"
    ..lastname = "lastname"
    ..age = "25";
  
  print("Hello, ${user.firstname} ${user.lastname}, you are ${user.age}!");
}

如果需要在操作块内直接执行逻辑(比如打印),可以结合匿名函数:

void main() {
  final user = User();
  () {
    user.firstname = "firstname";
    user.lastname = "lastname";
    user.age = "25";
    print("Hello, ${user.firstname} ${user.lastname}, you are ${user.age}!");
  }();
}

2. 自定义模拟with的函数

你可以自己封装一个顶层函数,完全模拟Kotlin with 的使用逻辑:

R with<T, R>(T receiver, R Function(T) block) {
  return block(receiver);
}

使用方式和Kotlin几乎一致:

void main() {
  final user = User();
  with(user, (u) {
    u.firstname = "firstname";
    u.lastname = "lastname";
    u.age = "25";
    print("Hello, ${u.firstname} ${u.lastname}, you are ${u.age}!");
  });
}

如果想进一步简化闭包内的写法,还可以通过扩展函数实现:

extension WithExtension<T> on T {
  R withBlock<R>(R Function(T) block) {
    return block(this);
  }
}

调用时:

void main() {
  final user = User();
  user.withBlock((u) {
    u.firstname = "firstname";
    u.lastname = "lastname";
    u.age = "25";
    print("Hello, ${u.firstname} ${u.lastname}, you are ${u.age}!");
  });
}

需要注意的是,Dart原生不支持像Kotlin那样在闭包内直接省略接收者前缀,自定义函数仍需显式引用参数,但已经能有效减少重复书写对象名的问题。


内容的提问来源于stack exchange,提问作者Mathieu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 14:35:15