天天看點

kotlin類型 非空 和空類型的處理

/**
 * Created by gacmy on //
 */
fun strLen(s:String) = s.length//會産生編譯錯誤 空指針異常
//fun strLenSafe(s: String?) = s.length // 類型後面加? 表明它可以為空值 但是你不能直接調用它的方法 否則會報錯
fun strLenSafe(s: String?):Int{//你必須判空
    if(s == null){
        return 
    }
    s?.toUpperCase()//等同于下面的語句 類調的執行個體調用方法 加上? 則不是空則正常調用 是空值則傳回空
    if(s!=null) s.toUpperCase() else null

      return s.length
}


fun strLenSafe1(s: String):Int{//你必須判空
    if(s == null){
        return 
    }
    s?.toUpperCase()//等同于下面的語句 類調的執行個體調用方法 加上? 則不是空則正常調用 是空值則傳回空
    if(s!=null) s.toUpperCase() else null

    return s.length
}
val x:String? = null
//var y:String = x;//你不可以指派給一個變量空值的類型

class Employee(val name: String, val manager: Employee)

fun managerName(employee: Employee): String? = employee.manager?.name

class Address(val streetAddress: String, val zipCode: Int, val city:String, val county: String)
class Company(val name: String, val address:Address?)
class Person1(val name: String, val company: Company?)

fun Person1.countyName(): String{
    val country = this.company?.address?.county
    return if(country != null) country else "Unknown"
}

//變量空值的時候 預設指派 ?:
fun foo(s : String?){
    val t: String = s ?: ""
}


fun strLenSafe2(s :String?): Int = s?.length ?: 

fun Person1.countyName1(): String{
    val country = this.company?.address?.county ?: "Unkonwn"
    return country
}


fun printShippingLabel(person: Person1){
    val address = person.company?.address ?: throw IllegalArgumentException("No address")//抛出異常
    with(address){
        println(streetAddress)
        println("$zipCode $city, $county")
    }
}
//as? 類型安全轉換 轉換不成功就是空值
class Person2(val firstName: String, val lastName: String){
    override fun equals(other: Any?): Boolean {
        val otherPerson = other as? Person2 ?: return false
        return otherPerson.firstName == firstName && otherPerson.lastName == lastName
    }

    override fun hashCode(): Int = firstName.hashCode()* + lastName.hashCode()
}
//如果空值 就抛出空指針異常// 隻有你确定這個值肯定不是空值的時候 才會使用這個符号
fun ignoreNulls(s: String?){
    val sNotNull: String = s!!
    println(sNotNull.length)
}

//let 函數 當一個空為值的時候什麼也不執行 不為空執行一個函數
fun sendEmailTo(email: String){
    println("Sending email to $email")
}
fun getTheBesPersonInTheWorld() : Person? = null


fun testLet(){
    val email:String? = "";
    email?.let { email -> sendEmailTo(email) }

    email?.let { sendEmailTo(it) }
    getTheBesPersonInTheWorld()?.let { sendEmailTo(it.name) }

}

//所有類的參數 和函數的參數預設都 type? 類型
fun <T> printHashCode(t: T){
    println(t?.hashCode())
}
//T的類型 Any?

fun <T: Any>printHashCode1(t: T){//T 限定了Any類型  是以會産生編譯錯誤 T為非空類型
    println(t.hashCode())
}

//java 空值 和 kotlin空值類型 互相轉換  @Nullable String = String?   @NotNull String = String


//kotlin 沒有原始類型 java int float double kotlin 的類型 都是引用類型
//但是編譯器 會分情況處理,如果你的Int 值是函數傳回值 它會将Int 作為int 處理 ,List<Int> 就會将它作為包裝類Integer處理
//如果你将原始類型 作為類的參數類型 kotlin 将他作為包裝類型 你想在集合裡面使用原始類型 可以使用第三方庫 Trove4J
fun Person.isOrderThan(other: Person) :Boolean?{
    if(age == null || other.age == null){
        return null
    }
    return age > other.age
}

fun testConversion(){
    val i = 
 //   val k: Long = i 轉換錯誤 int 類型不能轉為long
    //你需要顯示調用toType函數
    val k: Long = i.toLong()
//在java 裡面new Integer(42).equals(new Long(42)) return false
    val x = 
    val list = listOf(L,L,L)
    //x in list 編譯器不會通過 類型錯誤
    x.toLong() in list //你需要做顯示的轉換
    //在kotlin 裡面 Long 類型: 123L    Double 類型:0.12 2.0 1.2e10 1.2e-10
    //Float 類型 123.4f
    //二進制類型 0b 或者 0B
    //十六進制類型 0x 或者0X 例如 0xCA  0Xca
    //字元類型 '1' '/t'  '/u0009'

    //kotlin 有的情況 會自動轉換類型 例如 數字類型不需要加字尾和字首
    fun foo(l: Long) = println(l)
    val b: Byte = 
    val l = b+L
    foo()


}

//Any類型 是所有對象的父類 (非空對象)
//Any? 是所有對象的父類 (Type?)
val answer:Any =  //any 類型 會自動識别你聲明的類型
//Any 類型最後會被編譯為 java 的Object類型 它的通用方法 toString equals hashCode
//如果你想使用 wait notify Object的方法 你需要将Any類型轉換為Object類型

//Unit類型 相當于void 類型

fun f(): Unit{}
fun f1(){}//這兩種寫法都是可以的

interface Processor<T>{
    fun process(): T
}
class NoResultProcessor: Processor<Unit>{
    override fun process() {

    }
}


//Nothing 類型 函數永遠不傳回值

//一個函數 抛出異常 或者 死循環 就不會傳回類型
fun fail(message: String): Nothing
{
    throw IllegalArgumentException(message)
}

fun testNothing(){
    val company = Company("name",Address("ff",,"city","county"))
    val address = company.address ?: fail("No address")
    print(address.city)
}