2017-09-23 76 views
2

科特林标准库包含接收对象和该对象的方法,该'with' method定义为:在Scala中可以用'等价方法表示kotlin'吗?

public inline fun <T, R> with(receiver: T, block: T.() -> R): R = receiver.block() 

而且可以用作:

val str = "string" 
with(str) { 
    println(size)) // will print 6; equals to "string".size 
    println(substring(3)) // will print (ing); equals to "string".substring(3) 
} 

如何在Scala中定义类似的方法?

回答

7

在Scala中没有办法定义这样的方法,因为在Scala中不存在function literals with receiver的概念。

但是,斯卡拉的import是足够一般,您可以使用它而不是with。你的榜样将作为写:

val str = "string" 
import str._ 
println(length) 
println(substring(3)) 

注意size专门并不认同这一计划,因为它正好在String被隐拉皮条工作,所以我不得不使用length代替。但是,总的来说,这是我们使用的模式。

评论后编辑:如果你想明确地范围导入到你的代码的一部分,你可以用括号,这是始终允许范围内的事情做到:

val str = "string" 

{ 
    import str._ 
    println(length) 
    println(substring(3)) 
} 
println(length) // does not compile 

注意,空白行是必要的,否则将被解析为尝试调用"string"apply方法,{...}作为参数。为了避免这个问题,你可以使用locally方法:

val str = "string" 
locally { 
    import str._ 
    println(length) 
    println(substring(3)) 
} 
println(length) // does not compile 

locally本身并不做任何事情;它仅用于直观地突出显示大括号仅出于范围原因,并且通过扩展来帮助解析做正确的事情。

+0

我能看到的主要区别是kotlin的范围有限,而scala的导入范围并不是那么有限。尽管如此,它似乎是最好的斯卡拉是:) – pedrorijo91

+1

@ pedrorijo91我已经更新了我的答案来解决这个问题。 – sjrd

+0

'val str =“hello”:{def size:Int}'几乎可以工作,但'尺寸'不会警告反射访问。 (我希望在不知道转换名称或包装器的情况下避免反思。) –

相关问题