在按名调用参数中引用Scala类变量的实现方案咨询
解决方案
你的核心问题是:按名参数的作用域在类外部,无法访问类初始化后的内部成员。要让传入的代码块能引用类内变量/方法,需要把代码块设计成依赖类实例的函数,让类在初始化完成后把自身(或特定成员)传递给代码块。
方案1:传递类实例给代码块
把body定义为接收MyClass实例的函数,这样用户可以通过实例访问内部变量:
class MyClass[T](i: Int)(body: MyClass[T] => T) { var i2 = i // 初始化时把当前实例传给body val something = body(this) } // 使用示例 val myc = new MyClass(1) { instance => // 读取i2 println(s"当前i2的值:${instance.i2}") // 修改i2 instance.i2 = 10 // 返回最终结果给something instance.i2 * 2 } println(myc.something) // 输出20
方案2:仅暴露需要定制的成员(更安全)
如果不想暴露整个类实例,可以只传递i2的读写接口,限制用户的修改范围:
class MyClass[T](i: Int)(body: (() => Int, Int => Unit) => T) { private var i2 = i // 提供i2的读取和修改方法 private val getI2 = () => i2 private val setI2 = (v: Int) => i2 = v // 把读写接口传给body val something = body(getI2, setI2) } // 使用示例 val myc = new MyClass(1) { (get, set) => println(s"初始i2:${get()}") set(5) println(s"修改后i2:${get()}") get() + 3 } println(myc.something) // 输出8
原代码问题解析
原代码中body: => T是按名参数,它的求值作用域在创建MyClass的外部(即new MyClass(1)(...)的外层),此时MyClass的i2还未被初始化,也不在外部作用域中,因此会编译报错。只有让body的求值延迟到类内部,并且接收类实例或其成员作为参数,才能访问到内部变量。
内容的提问来源于stack exchange,提问作者l Steveo l
相关产品推荐
相关产品推荐

