什麼時候應該喜歡Kotlin擴充套件功能?
.
對於範圍界定,似乎沒有區別:兩者都可以在類和其他函式內部或外部宣告,並且都可以或不能同時具有可見性修飾符.
語言參考似乎不建議在不同情況下使用常規功能或擴充套件功能.
所以,我的問題是:擴充套件功能什麼時候比常規的非成員功能有優勢?而常規的擴充套件?
foo.bar(baz,baq)vs bar(foo,baz,baq).
它只是一個功能語義的提示(接收器絕對是焦點)還是在使用擴充套件功能的情況下,使程式碼更清潔/開啟機會?
擴充套件功能在少數情況下是有用的,而在其他情況下是強制性的:
慣用案例:
>當您要增強,擴充套件或更改現有的API.擴充套件功能是通過新增新功能來更改類的慣用方式.您可以新增extension functions 和extension properties .參見XML/jackson-module-kotlin/blob/master/src/main/kotlin/com/fasterxml/jackson/module/kotlin/Extensions.kt#L15-L32" rel="nofollow,noindex" target="_blank">Jackson-Kotlin Module 中的一個示例,為ObjectMapper類新增方法,簡化了TypeReference和泛型的處理.
>將null安全性新增到無法在null上呼叫的新方法或現有方法.例如String的String擴充套件函式.isNullOrBlank()允許您即使使用空字串也可以使用該函式,而不必首先進行自己的空檢查.函式本身在呼叫內部函式之前進行檢查.見documentation for extensions with Nullable Receiver
強制性案件:
>當您需要一個介面的內聯預設功能時,您必須使用擴充套件功能將其新增到該介面,因為您不能在介面宣告(行內函數必須是最終的,當前不允許在介面內).當您需要內聯版本的函式for example this code from Injekt 時,這很有用
>當您希望為不支援該用法的類新增(item in collection){…}支援.您可以新增遵循for loops documentation 中描述的規則的iterator()擴充套件方法 – 即使返回的類似迭代器的物件也可以使用擴充套件來滿足提供next()和hasNext()的規則.
>將運算子新增到現有類中,如*(專業化#1,但不能以任何其他方式執行此操作,因此是強制性的).見documentation for operator overloading
可選案例:
>你想控制對呼叫者可見的東西的範圍,所以你只能在允許呼叫可見的上下文中擴充套件類.這是可選的,因為您只能允許總是看到副檔名.see answer in other SO question for scoping extension functions
>您有一個介面,您想要簡化所需的實現,同時仍然允許更容易的幫助功能為使用者.您可以選擇為介面新增預設方法來幫助,或使用擴充套件功能新增介面的未預期實現部分.一個可以覆蓋預設值,另一個不(副檔名與成員的優先順序除外).
>當您想要將功能與功能類別相關聯時;擴充套件功能使用他們的接收器類作為從中找到它們的地方.他們的名字空間成為可以從中觸發的類(或類).而頂級函式將難以找到,並將填寫IDE程式碼完成對話方塊中的全域性名稱空間.您還可以修復現有的庫名稱空間問題.例如,在Java 7中,您有Path類,很難找到Files.exist(path)方法,因為它的名稱間隔奇怪.該函式可以直接放在Path.exists()上. (@kirill)
優先規則:
擴充套件現有的類時,請牢記優先順序規則.它們在KT-10806 描述為:
For each implicit receiver on current context we try members, then local extension functions(also parameters which have extension function type), then non-local extensions.
http://stackoverflow.com/questions/35317940/when-should-one-prefer-kotlin-extension-functions