2017-09-23 77 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}'幾乎可以工作,但'尺寸'不會警告反射訪問。 (我希望在不知道轉換名稱或包裝器的情況下避免反思。) –

相關問題