第三章 Kotlin 類型系統
類型系統是在計算機科學中,類型系統用于定義如何將編程語言中的數值和表達式歸類為許多不同的類型,如何操作這些類型,這些類型如何互相作用。類型可以確認一個值或者一組值具有特定的意義和目的(雖然某些類型,如抽象類型和函數類型,在程序運行中,可能不表示為值)。類型系統在各種語言之間有非常大的不同,也許,最主要的差異存在于編譯時期的語法,以及運行時期的操作實現方式。(百度百科)
本章我們主要簡單介紹Kotlin的類型相關的知識。
對象是帶有屬性和方法的特殊數據類型。筆者記得,在大學時候,學習C語言的結構體struct的時候,里面介紹過ADT(Abstract Data Type, 抽象數據類型)。其實,這就是對象。
Kotlin 是一門完全面向對象(Object Oriented)的語言。在Kotlin中一切皆是對象。所有對象皆繼承自Any(類似Java中的所有對象的祖先類Object)。
在 Kotlin 中,函數是對象,基本類型也是對象,所有東西都是對象:數字、字符、布爾和數組。同時,Kotlin提供多個內建對象(buildin object): Number,Char,Boolean,String,Array等。
這個跟JavaScript挺像的。JavaScript 中的所有事物都是對象:字符串、數值、數組、函數等等。此外,JavaScript 提供多個內建對象,比如 String、Date、Array 等等。
Kotlin 的類型表現起來有著高度的一致性。
基本數據類型
在Java 中,有基本類型。這使得Java的類型系統有點不倫不類。所以,在Kotlin與Java互操作時,遇到Java基本類型的時候,要小心點。這地方Kotlin的編譯器,會把Java的基本類型自動裝箱成對應的封裝類。
Kotlin的基本數據類型有:
Number: 包含整型與浮點型等
Char: 字符類型(Character)
Boolean: 布爾類型
String: 字符串類型
Array: 數組類型
在kotlin源碼工程中如下圖所示:
1.數字Number類型
Kotlin的基本數值類型包括Byte、Short、Int、Long、Float、Double等,這些類型都是內置類型。不同于Java的是,字符不屬于數值類型。 Kotlin 處理數字在某種程度上接近 Java,但是并不完全相同。例如,對于數字沒有隱式拓寬轉換( Java 中 int
可以隱式轉換為long
),另外有些情況的字面值略有不同。
類型 | 寬度 | 取值范圍 |
---|---|---|
Byte | 8 | -128~127 |
Short | 16 | -32768~32767 |
Int | 32 | -2147483648~2147483647 |
Long | 64 | -9223372036854775807L - 1L ~ 9223372036854775807L |
Float | 32 | 32位單精度浮點數 10-38~1038和-10-38~-1038 |
Double | 64 | 64位雙精度浮點數 10-308~10308和-10-308~-10308 |
在Kotlin內置的類型,有點像Java中的包裝類。當然它們與Java多少有些不同。
這些數字類型在kotlin-runtime.jar里面的kotlin包下面的Primitives.kt。在kotlin源碼工程中的core/buildins/native/kotlin/Primitives.kt。他們都繼承自kotlin.Number, kotlin.Comparable。在Number類里面定義了數字類型之間顯式轉換的函數:
package kotlin
/**
* Superclass for all platform classes representing numeric values.
*/
public abstract class Number {
/**
* Returns the value of this number as a [Double], which may involve rounding.
*/
public abstract fun toDouble(): Double
/**
* Returns the value of this number as a [Float], which may involve rounding.
*/
public abstract fun toFloat(): Float
/**
* Returns the value of this number as a [Long], which may involve rounding or truncation.
*/
public abstract fun toLong(): Long
/**
* Returns the value of this number as an [Int], which may involve rounding or truncation.
*/
public abstract fun toInt(): Int
/**
* Returns the [Char] with the numeric value equal to this number, truncated to 16 bits if appropriate.
*/
public abstract fun toChar(): Char
/**
* Returns the value of this number as a [Short], which may involve rounding or truncation.
*/
public abstract fun toShort(): Short
/**
* Returns the value of this number as a [Byte], which may involve rounding or truncation.
*/
public abstract fun toByte(): Byte
}
1.1自動向上轉型
Kotlin中沒有自動向上轉型,
val b: Byte = 1 // OK, 字面值是靜態檢測的
val i: Int = b // 錯誤
如果你想向上轉型,可以通過顯式地調用函數來實現:
var i: Int = 5;
var l: Long = i.toLong();
val i: Int = b.toInt() // OK: 顯式拓寬
這樣,類型之間關系更加清晰干凈。
1.2自動裝箱
在Kotlin中數值通過裝箱存儲。
val a: Int = 10000
print (a === a ) //打印 'true'
val boxedA: Int? =a
val anotherBoxedA: Int? = a
print (boxedA === anotherBoxedA ) // false
println (boxedA == anotherBoxedA )// true
從運行結果中可以看出,數值是相等的。但是引用地址不同。
1.3字面常量
在Kotlin的數字常量可以用十進制、十六進制、指數形式小數、二進制但是沒有八進制。數值常量字面值有以下幾種:
十進制: 123
Long 類型用大寫 L 標記: 123L
十六進制: 0x0F
二進制: 0b00001011
注意: Kotlin 不支持八進制,有點奇怪。
Kotlin 同樣支持浮點數的常規表示方法:
默認 double:123.5、123.5e10
Float 用 f 或者 F 標記: 123.5f
代碼示例:
val d = 123.4
println(d)
println(d::class.java)//double
數字字面值中的下劃線(自 1.1 起):
我們可以使用下劃線使數字常量更易讀:
val oneMillion = 1_000_000
val creditCardNumber = 1234_5678_9012_3456L
val socialSecurityNumber = 999_99_9999L
val hexBytes = 0xFF_EC_DE_5E
val bytes = 0b11010010_01101001_10010100_10010010
輸出:
1000000
1234567890123456
999999999
4293713502
3530134674
每個數字類型支持如下的轉換:
toByte(): Byte
toShort(): Short
toInt(): Int
toLong(): Long
toFloat(): Float
toDouble(): Double
toChar(): Char
缺乏隱式類型轉換并不顯著,因為類型會從上下文推斷出來,而算術運算會有重載做適當轉換,例如:
val l = 3L + 1
println(l)
println(l::class.java) // long, Long + Int => Long
1.4運算
Kotlin支持數字運算的標準集,運算被定義為相應的類成員(但編譯器會將函數調用優化為相應的指令)。
對于位運算,沒有特殊字符來表示,而只可用中綴方式調用命名函數,例如:
val x = (1 shl 2) and 0x000FF000
這是完整的位運算列表(只用于 Int
和 Long
):
-
shl(bits)
– 有符號左移 (Java 的<<
) -
shr(bits)
– 有符號右移 (Java 的>>
) -
ushr(bits)
– 無符號右移 (Java 的>>>
) -
and(bits)
– 位與 -
or(bits)
– 位或 -
xor(bits)
– 位異或 -
inv()
– 位非
這些運算函數定義在Primitives.kt中。
2.字符類型Char
字符類型在Kotlin中用Char
來表示。
val ch: Char = 'a'
println(ch::class.java)//char
val s = "abc"
println(s::class.java)//class java.lang.String
我們在JavaScript,Groovy可以使用單引號''
來標識字符串,但是Kotlin還是跟C,Java一樣,char類型只能是用單引號''
引用單個字符。當然,從編譯器的角度,完全可以通過字符數的多少來判斷是char類型還是String類型。
同時,Kotlin與Java不同的是,它不能直接去應用一個Number類型。例如
var c: Int = 'c'// 錯誤:類型不兼容
fun check(c: Char) {
if (c == 1) { // 錯誤:類型不兼容
// ……
}
}
是錯誤的。報錯信息:
Error:(29, 19) Kotlin: The character literal does not conform to the expected type Int
必須要顯式的調用函數進行轉換:
val c : Int = 'c'.toInt()
println(c)
fun check(c: Char) {
if (c.toInt() == 1) { // 顯式的調用函數進行轉換
// ……
}
}
fun decimalDigitValue(c: Char): Int {
if (c !in '0'..'9')
throw IllegalArgumentException("Out of range")
return c.toInt() - '0'.toInt() // 顯式轉換為數字
}
從這幾個細節,我們可以看出來自俄羅斯民族的Kotlin的節制的自由。
同樣Char也支持轉意字符\n、\b、\r等跟Java中的差不多:
字符字面值用單引號括起來:
'1'
。特殊字符可以用反斜杠轉義。
支持這幾個轉義序列:
\t
、\b
、\n
、\r
、\'
、\"
、\\
和\$
等。編碼其他字符要用 Unicode 轉義序列語法:
'\uFF00'
。
當需要可空引用時,像數字、字符會被裝箱。裝箱操作不會保留同一性。
3.布爾類型Boolean
布爾用 Boolean
類型表示,它有兩個值:true{: .keyword } 和 false{: .keyword }。
若需要可空引用布爾會被裝箱。
內置的布爾運算有:
-
||
– 短路邏輯或 -
&&
– 短路邏輯與 -
!
- 邏輯非
4.數組類型Array<T>
package kotlin
/**
* Represents an array (specifically, a Java array when targeting the JVM platform).
* Array instances can be created using the [arrayOf], [arrayOfNulls] and [emptyArray]
* standard library functions.
* See [Kotlin language documentation](http://kotlinlang.org/docs/reference/basic-types.html#arrays)
* for more information on arrays.
*/
public class Array<T> {
/**
* Creates a new array with the specified [size], where each element is calculated by calling the specified
* [init] function. The [init] function returns an array element given its index.
*/
public inline constructor(size: Int, init: (Int) -> T)
/**
* Returns the array element at the specified [index]. This method can be called using the
* index operator:
* value = arr[index]
*/
public operator fun get(index: Int): T
/**
* Sets the array element at the specified [index] to the specified [value]. This method can
* be called using the index operator:
* arr[index] = value
*/
public operator fun set(index: Int, value: T): Unit
/**
* Returns the number of elements in the array.
*/
public val size: Int
/**
* Creates an iterator for iterating over the elements of the array.
*/
public operator fun iterator(): Iterator<T>
}
數組在 Kotlin 中使用 Array
類來表示,它定義了 get
和 set
函數(按照運算符重載約定這會轉變為 []
)和 size
屬性,以及一些其他有用的成員函數:
class Array<T> private constructor() {
val size: Int
operator fun get(index: Int): T
operator fun set(index: Int, value: T): Unit
operator fun iterator(): Iterator<T>
// ……
}
我們可以使用
庫函數
arrayOf()
來創建一個數組并傳遞元素值給它,這樣arrayOf(1, 2, 3)
創建了 array [1, 2, 3]。庫函數
arrayOfNulls()
(初始化值為null),emptyArray
(其實現是(arrayOfNulls<T>(0) as Array<T>)) 可以用于創建一個指定大小、元素都為空的數組。
另一個選項是用接受數組大小和一個函數參數的工廠函數,用作參數的函數能夠返回。
給定索引的每個元素初始值:
// 創建一個 Array<String> 初始化為 ["0", "1", "4", "9", "16"]
val asc = Array(5, { i -> (i * i).toString() })
如上所述,[]
運算符代表調用成員函數 get()
和 set()
。
我們知道,Java的數組是協變的
。與 Java 不同的是,Kotlin 中數組是非協變的
(invariant)。
這意味著 Kotlin 不讓我們把 Array<String>
賦值給 Array<Any>
,以防止可能的運行時失?。ǖ悄憧梢允褂?Array<out Any>
。
Kotlin 也有無裝箱開銷的專門的類來表示原生類型數組,這些原生類型數組如下:
BooleanArray?—?Boolean類型數組
ByteArray?—?Byte類型數組
ShortArray?—?Short類型數組
IntArray?—?Int類型數組
LongArray?—?Long類型數組
CharArray?—?Char類型數組
FloatArray?—?Float類型數組
DoubleArray?— Double類型數組
這些類和 Array
并沒有繼承關系,但是它們有同樣的方法屬性集。它們也都有相應的工廠方法。這些方法定義在Library.kt中:
package kotlin
import kotlin.internal.PureReifiable
/**
* Returns a string representation of the object. Can be called with a null receiver, in which case
* it returns the string "null".
*/
public fun Any?.toString(): String
/**
* Concatenates this string with the string representation of the given [other] object. If either the receiver
* or the [other] object are null, they are represented as the string "null".
*/
public operator fun String?.plus(other: Any?): String
/**
* Returns an array of objects of the given type with the given [size], initialized with null values.
*/
public fun <reified @PureReifiable T> arrayOfNulls(size: Int): Array<T?>
/**
* Returns an array containing the specified elements.
*/
public inline fun <reified @PureReifiable T> arrayOf(vararg elements: T): Array<T>
/**
* Returns an array containing the specified [Double] numbers.
*/
public fun doubleArrayOf(vararg elements: Double): DoubleArray
/**
* Returns an array containing the specified [Float] numbers.
*/
public fun floatArrayOf(vararg elements: Float): FloatArray
/**
* Returns an array containing the specified [Long] numbers.
*/
public fun longArrayOf(vararg elements: Long): LongArray
/**
* Returns an array containing the specified [Int] numbers.
*/
public fun intArrayOf(vararg elements: Int): IntArray
/**
* Returns an array containing the specified characters.
*/
public fun charArrayOf(vararg elements: Char): CharArray
/**
* Returns an array containing the specified [Short] numbers.
*/
public fun shortArrayOf(vararg elements: Short): ShortArray
/**
* Returns an array containing the specified [Byte] numbers.
*/
public fun byteArrayOf(vararg elements: Byte): ByteArray
/**
* Returns an array containing the specified boolean values.
*/
public fun booleanArrayOf(vararg elements: Boolean): BooleanArray
/**
* Returns an array containing enum T entries.
*/
@SinceKotlin("1.1")
public inline fun <reified T : Enum<T>> enumValues(): Array<T>
/**
* Returns an enum entry with specified name.
*/
@SinceKotlin("1.1")
public inline fun <reified T : Enum<T>> enumValueOf(name: String): T
我們可以這樣使用原生類型數組:
val x: IntArray = intArrayOf(1, 2, 3)
x[0] = x[1] + x[2]
5.字符串類型String
字符串用 String
類型表示。字符串是不可變的。
代碼示例:
val c1 = 'c'
val c2 = "cc"
println(c1::class.java)//char
println(c2::class.java)//
訪問字符串的元素:可以使用索引運算符訪問: s[i]
。
可以用 foreach 循環迭代字符串:
for (c in str) {
println(c)
}
字符串字面值
Kotlin 有兩種類型的字符串字面值: 轉義字符串可以有轉義字符,以及原生字符串可以包含換行和任意文本。轉義字符串很像 Java 字符串:
val s = "Hello, world!\n"
轉義采用傳統的反斜杠方式。參見上面的 字符 查看支持的轉義序列。
原生字符串 使用三個引號("""
)分界符括起來,內部沒有轉義并且可以包含換行和任何其他字符:
val text = """
for (c in "foo")
print(c)
"""
你可以通過 trimMargin()
函數去除前導空格:
val text = """
for (c in "foo")
print(c)
"""
println(text)
val text2 = """
for (c in "foo")
print(c)
""".trim()
println(text2)
val text3 = """
|About.
|Kotlin.
|Easy Learning.
|(Jason Chen)
""".trimMargin("|")
println(text3)
輸出:
for (c in "foo")
print(c)
for (c in "foo")
print(c)
About.
Kotlin.
Easy Learning.
(Jason Chen)
默認 |
用作邊界前綴,但你可以選擇其他字符并作為參數傳入,比如 trimMargin(">")
。
字符串模板
字符串可以包含模板表達式 ,即一些小段代碼,會求值并把結果合并到字符串中。
模板表達式以美元符($
)開頭,由一個簡單的名字構成:
val i = 10
val s = "i = $i" // 求值結果為 "i = 10"
或者用花括號擴起來的任意表達式:
val s = "abc"
val str = "$s.length is ${s.length}" // 求值結果為 "abc.length is 3"
原生字符串和轉義字符串內部都支持模板。
如果你需要在原生字符串中表示字面值 $
字符(它不支持反斜杠轉義),你可以用下列語法:
val price = """
${'$'}9.99
"""
Kotlin類型系統
Kotlin有一個統一的類型系統,它有一個根類型kotlin.Any?。并且每個其他類型是此根類型的子類型。
Kotlin中的根對象Any
Kotlin中所有對象皆繼承自Any。這個Any類源碼如下:
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package kotlin
/**
* The root of the Kotlin class hierarchy. Every Kotlin class has [Any] as a superclass.
*/
public open class Any {
/**
* Indicates whether some other object is "equal to" this one. Implementations must fulfil the following
* requirements:
*
* * Reflexive: for any non-null reference value x, x.equals(x) should return true.
* * Symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true.
* * Transitive: for any non-null reference values x, y, and z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) should return true
* * Consistent: for any non-null reference values x and y, multiple invocations of x.equals(y) consistently return true or consistently return false, provided no information used in equals comparisons on the objects is modified.
*
* Note that the `==` operator in Kotlin code is translated into a call to [equals] when objects on both sides of the
* operator are not null.
*/
public open operator fun equals(other: Any?): Boolean
/**
* Returns a hash code value for the object. The general contract of hashCode is:
*
* * Whenever it is invoked on the same object more than once, the hashCode method must consistently return the same integer, provided no information used in equals comparisons on the object is modified.
* * If two objects are equal according to the equals() method, then calling the hashCode method on each of the two objects must produce the same integer result.
*/
public open fun hashCode(): Int
/**
* Returns a string representation of the object.
*/
public open fun toString(): String
}
關于學習一門語言的最好的方式,就是閱讀其源碼。通過這個Any類的源碼以及注釋,我們可以看出
判斷兩個對象x,y是否相等,必須滿足以下條件:
自反性:對于任何非空引用值x,x.equals(x)應返回true。
對稱性:對于任何非空引用值x和y,x.equals(y)應返回true當且僅當y.equals(x)返回true。
傳遞性:對于任何非空引用值x,y,z,如果x.equals(y)返回true,y.equals(Z)返回true,那么x.equals(Z)應返回true
一致性:對于任何非空引用值x和y,多次調用x.equals(y)始終返回true或者始終返回false,沒有提供任何信息進行相等比較的對象被修改。
另外,請注意,==
算子在Kotlin中,等價于調用equals
函數。要比較引用是否相同,使用===
算子。
Kotlin泛型與類型安全
跟Java一樣,Kotlin也支持泛型類:
package com.easy.kotlin
/**
* Created by jack on 2017/5/30.
*/
class Box<T>(t:T){
var value = t
}
在具體使用的時候,需要傳入具體的類型:
val box1 = Box<String>("easy kotlin")
println(box1.value)
Kotlin也可以通過值可以推斷出類型(type projections),所以,我們也可以省略類型參數:
// 1 的類型是 Int, 編譯器可以推斷出泛型T的類型是Int
val box2 = Box(1)
println(box2.value)
在Kotlin泛型中,數組類型Array是非協變的(Non covariant)。意思是,泛型類型參數是不可變的。例如Array<Int>
與Array<Any>
不是子父類關系,故無法將Array<Int>
的實例當做Array<Any>
使用。這么做,是為了類型安全。
在Java中的使用通配符類型的場景中,Kotlin通過使用關鍵字out,in來支持特殊場景下的協變(covariant)。
Java類型系統最復雜的特性之一,就是通配符。但是Kotlin中一個都沒有,取而代之的是兩種其他實現::
- declaration-site協變
- 類型預測(type projections)
首先,讓我們想一下,為什么Java需要如此難以理解的通配符。這個問題在《Effective Java》(Joshua Bloch)的第28節有解釋:
利用有限制的通配符來提高API的靈活性。
首先,Java中泛型的參數化類型是非協變的(invariant),這意味著List<String>并不是List<Object>的子類型。下面這段代碼將會帶來編譯異常以及運行時異常:
// Java
List<String> strs = new ArrayList<String>();
List<Object> objs = strs; // !!! 這就是即將引入的問題的原因。Java禁止這樣!
objs.add(1); // 我們向一個包含`String`的列表添加了一個`Integer`
String s = strs.get(0); // !!! ClassCastException: Cannot cast Integer to String
所以,Java禁止這樣做其實是為了保證運行時安全。
我們來看一下Collection接口的addAll()方法,這個方法的簽名是什么呢?直觀來看覺得可能會是這樣的:
// Java
public interface Collection<E> ... {
... addAll(Collection<E> items);
}
但是,addAll()的實際的簽名函數是下面這個樣子:
public interface Collection<E> ... {
// Java
... addAll(Collection<? extends E> c);
}
通配符唯一保證的事情就是類型安全(type safety)。
通配符類型參數(wildcard type argument) ? extends T
表明這個方法接受 T子類型的對象集合,并非T本身。這意味著,可以從列表中安全的讀取T(集合中所有的元素都是T的一個子類),但是我們無法寫入因為我們并不知道哪些類是T的子類。因為有了這種限制,我們渴望這種行為: Collection<String>是 Collection<? extends Object>的子類。從表面意義來看,通過extends-bound(向上限制)修飾的通配符使得類型可協變。
Java中的另一個通配符 List<? super String>
是List<Object>的超類。這被成為 逆變(contravariance)。
你只能使用String作為參數在List<? super String>
上調用方法( 你可以調用add(String)或者 set(int, String))。然而,如果當你調用List<T>的一些函數來返回T的話,你將會得到一個Object,而不是String。
Joshua Bloch稱:
這些對象你只能從生產者(Producers)中讀取,只能在消費者(Consumers)中寫入。為了最大程度的靈活性,在輸入參數時使用通配符類型來表示生產者或者消費者。
關于Kotlin的泛型,更多可以參考[1]
類型別名typealias
類型別名為現有類型提供替代名稱。這個跟Linux的shell中的命令行alias類似。
如果類型名稱太長,你可以另外引入較短的名稱,并使用新的名稱替代原類型名。
它有助于縮短較長的泛型類型。這樣可以簡化我們的代碼:
typealias NodeSet = Set<Network.Node>
typealias FileTable<K> = MutableMap<K, MutableList<File>>
為函數類型提供另外的別名:
typealias MyHandler = (Int, String, Any) -> Unit
typealias Predicate<T> = (T) -> Boolean
為內部類和嵌套類創建新名稱:
class A {
inner class Inner
}
class B {
inner class Inner
}
typealias AInner = A.Inner
typealias BInner = B.Inner
類型別名不會引入新類型。
當我們在代碼中添加 typealias Predicate<T>
typealias Predicate<T> = (T) -> Boolean
并使用 Predicate<Int>
時,Kotlin 編譯器總是把它擴展為 (Int) -> Boolean
。
因此,當我們需要泛型函數類型時,可以傳遞該類型的變量,反之亦然:
// 類型別名
typealias Predicate<T> = (T) -> Boolean
fun foo1(p: Predicate<Int>) = p(1)
fun foo2(p: Predicate<Int>) = p(-1)
fun main(args: Array<String>) {
val f: (Int) -> Boolean = { it > 0 }
println(foo1(f)) // 輸出 "true"
println(foo2(f)) // 輸出 "false"
val fn : (Int) -> Boolean = {it < 0}
println(foo1(fn)) // 輸出 "false"
println(foo2(fn)) // 輸出 "true"
val p: Predicate<Int> = { it > 0 }
println(listOf(1, -2).filter(p)) // 輸出 "[1]"
}
參考資料
1.http://kotlinlang.org/docs/reference/generics.html
Kotlin開發者社區
專注分享 Java、 Kotlin、Spring/Spring Boot、MySQL、redis、neo4j、NoSQL、Android、JavaScript、React、Node、函數式編程、編程思想、"高可用,高性能,高實時"大型分布式系統架構設計主題。
High availability, high performance, high real-time large-scale distributed system architecture design。
分布式框架:Zookeeper、分布式中間件框架等
分布式存儲:GridFS、FastDFS、TFS、MemCache、redis等
分布式數據庫:Cobar、tddl、Amoeba、Mycat
云計算、大數據、AI算法
虛擬化、云原生技術
分布式計算框架:MapReduce、Hadoop、Storm、Flink等
分布式通信機制:Dubbo、RPC調用、共享遠程數據、消息隊列等
消息隊列MQ:Kafka、MetaQ,RocketMQ
怎樣打造高可用系統:基于硬件、軟件中間件、系統架構等一些典型方案的實現:HAProxy、基于Corosync+Pacemaker的高可用集群套件中間件系統
Mycat架構分布式演進
大數據Join背后的難題:數據、網絡、內存和計算能力的矛盾和調和
Java分布式系統中的高性能難題:AIO,NIO,Netty還是自己開發框架?
高性能事件派發機制:線程池模型、Disruptor模型等等。。。
合抱之木,生于毫末;九層之臺,起于壘土;千里之行,始于足下。不積跬步,無以至千里;不積小流,無以成江河。
Kotlin 簡介
Kotlin是一門非研究性的語言,它是一門非常務實的工業級編程語言,它的使命就是幫助程序員們解決實際工程實踐中的問題。使用Kotlin 讓 Java程序員們的生活變得更好,Java中的那些空指針錯誤,浪費時間的冗長的樣板代碼,啰嗦的語法限制等等,在Kotlin中統統消失。Kotlin 簡單務實,語法簡潔而強大,安全且表達力強,極富生產力。
Java誕生于1995年,至今已有23年歷史。當前最新版本是 Java 9。在 JVM 生態不斷發展繁榮的過程中,也誕生了Scala、Groovy、Clojure 等兄弟語言。
Kotlin 也正是 JVM 家族中的優秀一員。Kotlin是一種現代語言(版本1.0于2016年2月發布)。它最初的目的是像Scala那樣,優化Java語言的缺陷,提供更加簡單實用的編程語言特性,并且解決了性能上的問題,比如編譯時間。 JetBrains在這些方面做得非常出色。
Kotlin語言的特性
用 Java 開發多年以后,能夠嘗試一些新的東西真是太棒了。如果您是 Java 開發人員,使用 Kotlin 將會非常自然流暢。如果你是一個Swift開發者,你將會感到似曾相識,比如可空性(Nullability)。 Kotlin語言的特性有:
1.簡潔
大幅減少樣板代碼量。
2.與Java的100%互操作性
Kotlin可以直接與Java類交互,反之亦然。這個特性使得我們可以直接重用我們的代碼庫,并將其遷移到 Kotlin中。由于Java的互操作性幾乎無處不在。我們可以直接訪問平臺API以及現有的代碼庫,同時仍然享受和使用 Kotlin 的所有強大的現代語言功能。
3.擴展函數
Kotlin 類似于 C# 和 Gosu, 它提供了為現有類提供新功能擴展的能力,而不必從該類繼承或使用任何類型的設計模式 (如裝飾器模式)。
4.函數式編程
Kotlin 語言一等支持函數式編程,就像Scala一樣。具備高階函數、Lambda 表達式等函數式基本特性。
5.默認和命名參數
在Kotlin中,您可以為函數中的參數設置一個默認值,并給每個參數一個名稱。這有助于編寫易讀的代碼。
6.強大的開發工具支持
而由于是JetBrains出品,我們擁有很棒的IDE支持。雖然Java到Kotlin的自動轉換并不是100% OK 的,但它確實是一個非常好的工具。使用 IDEA 的工具轉換Java代碼為 Kotlin 代碼時,可以輕松地重用60%-70%的結果代碼,而且修改成本很小。
Kotlin 除了簡潔強大的語法特性外,還有實用性非常強的API以及圍繞它構建的生態系統。例如:集合類 API、IO 擴展類、反射API 等。同時 Kotlin 社區也提供了豐富的文檔和大量的學習資料,還有在線REPL。
A modern programming language that makes developers happier. Open source forever