簡體   English   中英

Kotlin 擴展函數與成員函數?

[英]Kotlin extension functions vs member functions?

我知道 Kotlin 中使用擴展函數來擴展類的功能(例如,來自庫或 API 的功能)。

但是,在代碼可讀性/結構方面,使用擴展函數是否有任何優勢:

class Foo { ... }

fun Foo.bar() {
    // Some stuff
}

與成員函數相反:

class Foo {

    ...

    fun bar() {
        // Some stuff
    }
}

?

有推薦的做法嗎?

何時使用成員函數

如果以下所有條件都適用,您應該使用成員函數:

  • 代碼最初是用 Kotlin 編寫的
  • 你可以修改代碼
  • 該方法可以從任何其他代碼中使用

何時使用擴展函數

如果以下任何一種情況適用,您應該使用擴展函數:

  • 代碼最初是用 Java 編寫的,您想添加用 Kotlin 編寫的方法
  • 您不能更改原始代碼
  • 你想要一個只對代碼的特定部分有意義的特殊函數

為什么?

通常,成員函數比擴展函數更容易找到,因為它們保證在它們所屬的類(或超類/接口)中。

它們也不需要導入到使用它們的所有代碼中。

在我看來,使用擴展函數有兩個令人信服的理由:

  1. 要“擴展”類的行為,您不是/無法更改(以及繼承沒有意義或不可能的地方)。

  2. 為特定功能提供范圍。 例如,一個擴展函數可以被聲明為一個獨立的函數,在這種情況下它可以在任何地方使用。 或者您可以選擇將其聲明為另一個類的(私有)成員函數,在這種情況下,它只能在該類內部使用。

聽起來#1 在您的情況下不是問題,因此實際上更應該歸結為#2。

擴展函數類似於您創建的實用函數。

一個基本的例子是這樣的:

// Strings.kt
fun String.isEmail() : Boolean {
    // check for email pattern and return true/false
}

這段代碼可以寫成 Java 中的一個實用函數,如下所示:

class StringUtils {
    public static boolean isEmail(String email) {
        // check for email pattern and return true/false
    }
}

所以它本質上所做的是,使用您調用的對象調用相同的函數將作為第一個參數傳遞給參數。 就像我在Java給出的例子一樣。

如果要從java調用在kotlin創建的擴展函數,則需要將調用者作為第一個參數傳遞。 像,

StringsKt.isEmail("example@example.com")

根據文檔,

擴展實際上並不修改它們擴展的類。 通過定義擴展,您不會將新成員插入到類中,而只是使新函數可以使用這種類型的變量上的點符號調用。

它們只是靜態函數,調用者作為第一個參數,其他參數緊隨其后。 它只是擴展了我們以這種方式編寫它的能力。

什么時候創建擴展函數?

  • 當您無權訪問該類時。 當該類屬於您尚未創建的某個庫時。
  • 對於原始類型。 整數、浮點數、字符串等。

使用擴展函數的另一個原因是,您不必為了使用這些方法而擴展該類,就好像它們屬於該類(但實際上不是該類的一部分)。

希望它對你有點清楚..

正如其他答案中提到的,擴展函數主要用於您無法更改的代碼中 - 也許您想將圍繞某個庫對象的復雜表達式更改為更容易和更易讀的表達式。

我的看法是對data classes使用擴展函數。 我的推理純粹是哲學上的, data classes應該只用作數據載體,它們不應該攜帶狀態並且它們本身不應該做任何事情。 這就是為什么我認為您應該使用擴展函數以防萬一您需要圍繞data class編寫函數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM