Kotlin基礎語法-05-運算符重載-中綴表達式
接上篇文章本文主要從kotlin 中的運算符重載、中綴表達式、反引號與typealies、 對象比較與值比較、DSL的基本概念、
1.運算符重載
來看一段代碼
fun main( args : Array<String>){
/// 這裏的step 就是步進、中綴表達式。
for( i in 1..1000 setp 20 ){
print("$i")
}
}
編譯後就會in就會被編譯成一個Int迭代器, 稍有基礎就能看懂、 不再贅述、
override fun iterator(): IntIterator = IntProgressionIterator(ifrst, last, step)
internal class IntProgressionIteraotr(first: Int, last: Int, val step : Int):IntIterator{
private var next = first
private val finalElement = last
private var hasNext :Boolean if (step>0) first <=last else first > = last
override fun hasNext(): Boolean = hasNext
override fun nextInt():Int{
val value = next
if(value == finalElement){
hasNext = false
}else{
next += setp
}
return value
}
}
kotlin 中的運算符重載使用的是operator 關鍵字實現、修飾fun 時候後、 表示重載了函數名指代的運算符、
在結構的時候 ,我們標記過:
operator : 將一個函數標記爲重載一個操作符或者實現一個約定。
再來一段代碼
for( i in 1.rangeTo 20 ){
println("$i")
}
運算符的重載只能是在kotlin中定義好的、不能憑空來造。運算符是有上限的、
現在一共有120幾個吧、
/// 看到了吧、這就是運算符重載的方法、
public operator fun rangeTo(other: Int) : IntRange
// 當然還有String + 號 也是重載
public opterator fun plus(other:Any?):String
2.中綴表達式
當然如果重載運算符不夠用、這時候就需要使用中綴表達式
來個例子,
fun main(args: Array<String>) {
println(5 vs 6)
println(5.7 vs 2.3)
}
/**
* 密閉類的三個值、
*/
sealed class CompareResult {
object MORE : CompareResult() {
override fun toString(): String {
return "more"
}
}
object LESS : CompareResult() {
override fun toString(): String {
return "less"
}
}
object EQUAL : CompareResult() {
override fun toString(): String {
return "equal"
}
}
}
/**
* Int 是該函數的接受者類型、也就是說只能是該類型可以調用該方法
*/
infix fun Int.vs(num: Int): CompareResult {
if (this - num < 0) {
return CompareResult.LESS
} else if (this - num > 0) {
return CompareResult.MORE
} else {
return CompareResult.EQUAL
}
}
infix fun Float.vs(num:Float):CompareResult=
if(this-num<0){
CompareResult.LESS
}else if(this- num>0){
CompareResult.MORE
}else{
CompareResult.EQUAL
}
infix fun Double.vs(num:Double):CompareResult=
if(this-num<0){
CompareResult.LESS
}else if(this - num >0){
CompareResult.MORE
}else{
CompareResult.EQUAL
}
打印結果:
less
more
Process finished with exit code 0
一個函數只有用於兩個角色類似的對象時纔將其聲明爲中綴函數。
推薦: and 、 to 、 zip
反例: add
最重要的一點:
如果一個方法會改動其接受者,那麼不要聲明爲中綴表達式。
3. kotlin 的反引號``與typealies 和對象比較與值比較
///
fun `123456`():Unit{
println("test1")
}
123456一羣數字肯定是沒有意義的, 在java中也不能夠作爲一個方法名稱,但是在kotlin中添加了``引號,則可以作爲一個方法名使用,而且可以正常的調用。
注意: 這種寫法只用於kotlin中,而且不推薦使用。因爲調用起來很操心, 不省心。
例如``中間是一個空格,兩個空格也是一個方法,這時候可能因爲編程習慣多打了一個空格而造成調用方法的不同, 同時這麼寫也不能夠讓java代碼調用。
public typealias A = File
fun main(args: Array<String>){
///// 這麼聲明是合法的,
var a : File = A("/kotlinlearn/dev/xxx.json")
}
有一種類似於C/C++ 中的define 、宏定義的感覺。
再找一下koltin中類似映射的,例如:
@SinceKotlin("1.1") public typealias Error = java.lang.Error
@SinceKotlin("1.1") public typealias Exception = java.lang.Exception
@SinceKotlin("1.1") public typealias RuntimeException = java.lang.RuntimeException
@SinceKotlin("1.1") public typealias IllegalArgumentException = java.lang.IllegalArgumentException
@SinceKotlin("1.1") public typealias IllegalStateException = java.lang.IllegalStateException
@SinceKotlin("1.1") public typealias IndexOutOfBoundsException = java.lang.IndexOutOfBoundsException
@SinceKotlin("1.1") public typealias UnsupportedOperationException = java.lang.UnsupportedOperationException
@SinceKotlin("1.1") public typealias NumberFormatException = java.lang.NumberFormatException
@SinceKotlin("1.1") public typealias NullPointerException = java.lang.NullPointerException
@SinceKotlin("1.1") public typealias ClassCastException = java.lang.ClassCastException
@SinceKotlin("1.1") public typealias AssertionError = java.lang.AssertionError
@SinceKotlin("1.1") public typealias NoSuchElementException = java.util.NoSuchElementException
@SinceKotlin("1.1") public typealias Comparator<T> = java.util.Comparator<T>
這裏有一部分kotlin 中的類,映射的java中的類, 這樣就形成了隔離層,既保留了java中的特性,又方便了kotlin 中的維護。
4. kotlin中如何比較對象
我們知道在java中A==B代表的意思是對象A與對象B是否相同,比較的是堆內存地址是否相同。
而例如String 的equals 代表的意思是對象A與對象B的值是否相同。
其實記住這句話就行了, 但是在kotlin中A == B代表的是對象A與B的值是否相同,而A===B則表示對象A與對象B是否是相同的對象
5. 外部DSL與內部DSL
什麼是DSL語言, 怎麼還區分外部和內部?
很簡單, DSL 就是(Domain Specific Language ) 領域專用語言。例如json , xml , css, makefile, anko,kolley, build.gradle 這些就是。
外部內部的區分就是, 不依賴其他語言而且能都獨自定義的就是外部的, 反之就是內部的。
舉個例子,
例如json 就是表達了數據傳輸格式。 xml 既表達數據格式,也可以表示配置, 重要的是不依賴外部語言。
而anko ,kolley 就嚴重依賴了kotlin 才能夠使用的,
例如anko 就是基於kotlin開發的
能夠類似於butterknife的一個框架。 而kolley 則是類似於volley的一個網絡請求架構。
注意, 不管內部DSL還是外部DSL 其特點是專有的,特殊領域內使用的,不要求複雜,包含所有,只要求精而專一。
6. 總結
多上手敲、多嘗試、多思考、 有問題評論區我們共同討論進步。