kotlin 擴充套件函式和運算子過載

2021-10-24 04:33:17 字數 4535 閱讀 7989

擴充套件函式表示即使在不修改某個類的原始碼的情況下,仍然可以開啟這個類,向該類新增新的函式

如果想統計字串中字母的數量,你可能會寫出如下函式:

object stringutil 

}return count}}

呼叫時

stringutil.

lettercount

("123abc456def"

)

有了擴充套件函式,我們可以使用一種更加物件導向的思維來實現這個功能,比如說將 lettercount() 方法新增到 string 類中

先來學習擴充套件函式語法結構

fun classname.

methodname

(param1: int, param2: int)

: int

相對於定義乙個普通的函式,定義擴充套件函式只需要在函式名前加上乙個 classname. 的語法結構,就表示將該函式新增到指定類當中了

由於我們希望向 string 類中新增乙個擴充套件函式,因此需要先建立乙個 string.kt 檔案。檔名雖無固定要求,但建議向哪個類新增擴充套件函式,就定義乙個同名 kotlin 檔案。當然擴充套件函式也是可以定義在任何乙個現有類當中,不一定非要建立新檔案。通常來說,最好將它定義成頂層方法,這樣可以讓擴充套件函式擁有全域性的訪問域

string.kt 中編寫如下**:

fun string.

lettercount()

:int

}return count

}

現在我們將 lettercount() 方法定義成了 string 類的擴充套件函式,那麼函式就擁有了 string 例項的上下文,因此不需要再接收乙個字串引數了,直接遍歷 this 即可,因為 this 就代表字串本身

使用時

"123abc456def"

.lettercount

()

運算子過載使用的是operator關鍵字,只要在指定函式前面加上operator關鍵字就可以實現運算子過載功能了。我們以加號運算子為例,來實現兩個物件相加的功能

class obj 

}

上述語法結構中關鍵字 operater 和函式名 plus 都是固定不變的,接收引數和返回值根據你自己的邏輯設定。那麼上述**就表示乙個 obj 物件可以與另乙個 obj 物件相加,最終返回新的 obj 物件。對應呼叫方式如下:

val obj1 =

obj(

)val obj2 =

obj(

)val obj3 = obj1 + obj2

最後兩個物件相加看起來很神奇,它會在編譯的時候被轉換成 obj1.plus(obj2) 的呼叫方式

下面實現乙個功能:讓兩個 money 物件相加

首先定義好 money 類的結構,讓 money 主建構函式接收乙個 value 引數,用於表示錢的金額,然後使用運算子過載實現兩個 money 相加,建立 money.kt 檔案:

class

money

(val value:int)

}

測試

val money1 =

money(5

)val money2 =

money(10

)val money3 = money1 + money2

println

(money3.value)

列印結果

如果 money 物件能直接和數字相加就更好了,我們可以實現這個功能,因為 kotlin 允許我們對同乙個運算子進行多重過載:

class

money

(val value:int)

operator

funplus

(int: int)

:money

}

使用

val money1 =

money(5

)val money2 = money1 +

10println

(money2.value)

語法糖表示式和實際呼叫函式對照表

表示式函式名

a + bplus

a - bminus

a * btimes

a / bdiv

a % brem,mod(棄用)

表示式函式名

+aunaryplus

-aunaryminus

!anot

++a, a++inc

--a, a--dec

表示式函式名

a == ba?.equals(b) ?: (b === null)

a != b!(a?.equals(b) ?: (b === null))

a > ba.compareto(b) > 0

a < ba.compareto(b) < 0

a >= ba.compareto(b) >= 0

a <= ba.compareto(b) <= 0

表示式函式名

a..ba.rangeto(b)

a[b]a.get(b)

a[b] = ca.set(b,c)

a in bb.contains(a)

最後乙個a in b表示判斷 a 是否在 b 中,而b.contains(a)表示 b 是否包含 a

kotlin 中 string 類就對 contains() 函式進行了過載,因此當我們判斷 「hello」 中是否包含 「he」 可以這樣寫

if

("hello"

.contains

("he"))

借助過載的語法糖表示式,還可以這樣寫

if

("he"

in"hello"

)

我們之前使用過乙個隨機生成字串長度的函式

fun

getrandomlenthstring

(str:string)

:string

return builder.

tostring()

}

我們可以讓乙個字串乘以乙個數字來簡化上面的方法,因此我們在 string.kt 中加入:

operator

fun string.

times

(int:int)

:string

return builder.

tostring()

}

使用

log.d(

"mainactivity"

,"this is content "*3

)

另外必須說明的是,kotlin 類中已經提供了乙個用於將字串重複 n 遍的repeat()函式了,因此times()函式可以進一步精簡為

operator

fun string.

times

(int:int)

=repeat

(int)

因此剛才的getrandomlenthstring()函式可以使用這種寫法了:

fun

getrandomlenthstring

(str:string)

= str *(1

..20).

random

()

擴充套件運算子和rest運算子

擴充套件運算子用三個點號表示,功能是把陣列或類陣列物件展開成一系列用逗號隔開的值 一 拆分陣列 擴充套件運算子可以直接把陣列拆分成用逗號隔開的值 template section class p 10 el button type danger click get 點選 el button sect...

擴充套件運算子

三個點,主要是用來將陣列幻化為用逗號分隔的引數序列。合併陣列 與解構賦值結合 如果將擴充套件運算子用於陣列賦值,只能放在引數的最後一位,否則會報錯。將字串轉為真正的陣列 可以將類似陣列的物件轉為真正的陣列 map和set結構,generator函式 擴充套件運算子內部呼叫的是資料解構的iterato...

擴充套件運算子

首先點明,es6的新特性之擴充套件運算子 spread 就是三個點 和es6的可變引數形式一樣。擴充套件運算子是很強大的乙個運算子,它能簡化很多在es5中會比較繁雜的操作。對於這個運算子,概念性的東西不多,所以這裡我就簡明扼要的給出一些它的常用場景 1 可變引數。雖然可變引數嚴格說不是擴充套件運算子...