kotlin使用初體驗(yàn)

google宣布Kotlin作為andorid一級開發(fā)語言有一段時(shí)間了。在這段時(shí)間蛛碌,我也在新的模塊上嘗試使用了kotlin進(jìn)行開發(fā)颅筋,經(jīng)過這一段時(shí)間的開發(fā)玩讳,我覺得在開發(fā)中使用kotlin是個(gè)很棒的選擇。

使用Kotlin的很容易刮萌,只需要進(jìn)行幾步簡單的設(shè)置

  • android studio安裝下面兩個(gè)插件驮配,其中Parcelable Code Generator不是必要的,主要用于序列化Parcelable着茸,所示最好也安裝一下
    image.png
  • build.grade文件中添加依賴compile "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
  • build.grade文件中應(yīng)用插件
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'

通過以上的幾步壮锻,就可以開始我們的kotlin之旅了

1. 變量

kotlin中變量使用var、val來表示涮阔,var表示可變變量猜绣,val表示不可變變量(相當(dāng)于java當(dāng)中的final)。如下所示

var name: String="ivy"
val age=12

kotlin定義變量時(shí)可以不指定變量類型敬特,kotlin會根據(jù)你的賦值進(jìn)行判斷該變量的類型掰邢,如例子所示會自動(dòng)把age設(shè)置為Int類型,這里需要注意的是如果需要把變量賦值為Null(var name:String?="ivy")伟阔,需要加上辣之?號才表示該變量可以為Null

2. 函數(shù)

kotlin方法的使用和java的類似,當(dāng)沒有返回值的時(shí)候可以不寫减俏,或者寫Unit

fun add(one: Int , two: Int) : Int{
    return one+two
}

同時(shí)召烂,函數(shù)還可以為每個(gè)參數(shù)設(shè)置默認(rèn)值,這樣就可以避免多參數(shù)時(shí)定義多個(gè)方法,如下所示娃承。

fun add(one:Int , two: Int ,three: Int=0){
  //當(dāng)參時(shí)沒有設(shè)置three的值時(shí)奏夫,three默認(rèn)為0
}

這里有一個(gè)比較重要的概念怕篷。在kotlin當(dāng)中函數(shù)是一級公民,即函數(shù)也是可以作為變量酗昼、返回值來使用的廊谓,如下所示

val add=fun (a: Int,b: Int){ println(a+b) }
add(1,2)

可能有的小伙伴就要說,這有什么卵用麻削,我直接寫個(gè)方法蒸痹,然后調(diào)用方法不就好了。是呛哟,如果只是簡單的調(diào)用是可以叠荠,那如果把函數(shù)作為方法的參數(shù),這在java就無法做到了扫责,而把函數(shù)作為參數(shù)能給我們帶來很大的方便榛鼎,代碼看起來也更有邏輯性。如下所示

fun judgeHasMoney(doHappyThing: ()->Unit){
        if (User.hasMoney()){
            println("no money")
        }else{
            doHappyThing()
        }
}
judgeHasMoney(BuyCompany())
judgeHasMoney(BuyPhone())

這就可以非常方便對能否能購買東西進(jìn)行判斷鳖孤,代碼少了者娱,看上去也更有邏輯性。還有很多函數(shù)作為一級公民好處的實(shí)例苏揣,這里就不一一演示了黄鳍,for循環(huán)、List平匈、Map之類的太量操作符也是利用了這個(gè)特性進(jìn)行實(shí)現(xiàn)框沟。

3. 類的定義

class Boy(var name: String) : Person, interface{
        init {
            
        }
        constructor(name:String,age: Int) : this(name) {
            
        }
    }

如例子所示,這就是kotlin中類的定義吐葱。無論是接口還是父類都是寫在冒號后面街望,用逗號分割,不再使用extendsimplement弟跑。在kotlin中灾前,分主構(gòu)造函數(shù)和次構(gòu)造函數(shù),主構(gòu)造函數(shù)就是類名Boy括號后面參數(shù)(如果想在類中直接使用構(gòu)造函數(shù)的參數(shù)孟辑,需要加上val或者var),次構(gòu)造函數(shù)必須以constructor開頭哎甲,并且必須繼承調(diào)用主構(gòu)造函數(shù),所有的構(gòu)造函數(shù)初始化后都會調(diào)用 Init{}方法饲嗽,所以可以在Init()當(dāng)中進(jìn)行初始化操作炭玫。
kotlin類中還有一些需要注意的:

  • 1 在Kotlin中,所有的方法都是不開放的(即子類無法重寫)貌虾,如果子類要重寫父類的方法吞加,需要在父類方法前面加上open
  • 2 如果繼承了兩個(gè)類中含有共同的方法,可以通過super<類名>.方法名進(jìn)行調(diào)用
class SuperMan(): Person(), Boy {
        override fun run(){
            super<Person>.run()
        }
    }
  • 3 生成一個(gè)對象很簡單,直接var girl=Girl()就可以衔憨,不再需要new一個(gè)妹子了

4. 空安全

android開發(fā)中叶圃,空指針異常是最讓我們頭痛的也是導(dǎo)致應(yīng)用崩潰率最高的問題。我們之前已經(jīng)提到過践图,在kotlin中掺冠,在定義變量的時(shí)候就需要指定變量是否允許為空,這在一定程度上幫助我們減少空指針異常的可能性码党。但是還是不能完成避免空指針的出現(xiàn)德崭,因?yàn)橛行┳兞烤褪强煽湛刹粸榭眨?dāng)我們調(diào)用時(shí)揖盘,就有可能因?yàn)闆]有做出判斷而出現(xiàn)空指針異常眉厨。kotlin也考慮到這個(gè)問題,所以在調(diào)用可為空的變量時(shí)扣讼,kotlin會要求我們加上缺猛?號,如下所示:

var school?=Class()
school?.grade?.class?student?.size()

如果我們想查找一個(gè)班的學(xué)生的人數(shù)椭符,可以使用以上的方法,就可以獲取到學(xué)生的人數(shù)耻姥,當(dāng)中的任何一個(gè)變量為空销钝,后面的都不會繼續(xù)執(zhí)行,這個(gè)鏈?zhǔn)秸{(diào)用就會返回null琐簇,避免任何一個(gè)階段為空出現(xiàn)NPE的問題蒸健。

5. List、Map的使用

在開發(fā)中婉商,ListMap是我們最經(jīng)常用到的類了似忧。在kotlin中,ListMap也分為可變和不可變

var a = listOf(4)
var b = mutableListOf<String>()
var c = mapOf(Pair("3","4"))
var d = mutableMapOf<String,String>()

不可變的概念即和數(shù)組類似丈秩,只能夠改變每個(gè)位置的值盯捌,不能減少或者增加size
遍歷List有三種比較常用的方法

for(position in list.indices){
         //每一個(gè)位置遍歷
 }
       
for(str in list){
       //每一個(gè)對象遍歷    
}

for((position,str) in list.withIndex()){
       //每一個(gè)位置和對象遍歷     
}

遍歷Map比較常用的方法

for((key,value) in map){
            
 }

kotlin的遍歷方法相對于java來說,還是很方便和實(shí)用的蘑秽,但是=戎!肠牲!這不是最好用的S姿ァ!最方便的是kotlin加入了一系列的操作符缀雳,使用Rx的小伙伴應(yīng)該知道操作符有多棒渡嚣。下面我就來演示一個(gè)例子,查找一個(gè)班里面年齡超過15歲的女生名字
java:看我的

for(student in students){
   if(student.getSex()=="girl"&&student.getAge>15){
        System.out.println(student.getName())
    }
}

kotlin:小樣,看我的

students.filter{ it.sex=="girl" }
        .filter{ it.age>15 }
        .forEach{ print(student.name") }

是不是整個(gè)邏輯一目了然识椰。但是扬绪,有些喜歡挑事的小伙伴可能就會說我覺得上面那個(gè)沒有很方便啊。我就喜歡上面那個(gè)裤唠。
好挤牛,那我就再給你舉兩個(gè)例子,你寫java代碼對比一下

  • 1 15歲以上的女生是否有單身的V终骸D垢啊!
 students.filter { it.sex=="girl" }
                .filter { it.age >15 }
                .any{ !it.hasBoyFriend }
  • 2 把15歲以上的女生年齡排序一下航瞭,打印出名字
students.filter { it.sex=="girl" }
                .filter { it.age >15 }
                .sortedBy { it.age }
                .forEach { print(it.name) }

還有其它更棒诫硕,更好用的操作符,大家可以查看源碼刊侯。操作符可以大大提高開發(fā)速度章办,我在這里就不一一展示了(Map一樣有各種好用的操作符)

6. 流程控制

  • 1 for語句的使用和java的類似,也包含了很多的操作符(和List類似)
for(i in 0 .. 100){
     //0到100       
}        
 for(i in 0 until 100){
      //0到99      
}    
for (i in 100 downTo 0){
     //100到0           
}
  • 2 在java中滨彻,when語句中的case判斷只能是int藕届,后來也支持了String,但是支持的類型還是很少亭饵。而且休偶,只支持相同的類型,這樣就導(dǎo)致我們在開發(fā)中遇到復(fù)雜業(yè)務(wù)的時(shí)候辜羊,往往還需要在case中編寫if語句踏兜,這就給我?guī)砹撕艽蟮穆闊掖a也比較混亂八秃。但是kotlinwhen語句很好的解決了這個(gè)問題碱妆。當(dāng)when(x)有參數(shù)時(shí),可以在參數(shù)中添加參數(shù)所屬類型的表達(dá)式昔驱。當(dāng)when不帶參數(shù)時(shí)疹尾,可以添加各種表達(dá)式和方法,而不只是常量舍悯。
when (x) {
            1 -> print("x == 1")
            2,3 -> print("x == 2 or 3")
            in 10..20 -> print("x is in the range")
            else -> { // 注意這個(gè)塊
                print("x is shen me gui")
            }
        }
var x:Int=0
        when {
            x==1 -> print("x == 1")
            x in 10..20 -> print("x is in the range")
            isBigNum(x) -> print("big")
            else -> { // 注意這個(gè)塊
                print("x is shen me gui")
            }
        }
  • 3 在循環(huán)中航棱,java經(jīng)常會用到break跳出循環(huán),那kotlin是怎么實(shí)現(xiàn)的呢萌衬?請看例子饮醇,可以通過直接標(biāo)簽的形式,回到指定位置秕豫,和java類似
tag@ for (i in 0..100) {
  for (j in 0..100) {
    if (i==j)
      break@tag
  }
}

7. 數(shù)據(jù)類

相信java的小伙伴從剛開始學(xué)java的時(shí)候就知道建立對象先寫個(gè)javabean朴艰,要寫get观蓄、set方法,比較的時(shí)候要重寫equal等方法祠墅,copy對象的時(shí)候要實(shí)現(xiàn)Cloneable接口侮穿。非常的麻煩,而且容易出錯(cuò)毁嗦。kotlin給出了一種簡單的方法
data class person(var age: int ,var name: String)
編繹器會自動(dòng)使該Bean擁有以下特性:

  • 1get/set方法亲茅,當(dāng)var改為val時(shí),則沒有set方法
  • 2 equals()/hashCode()
  • 3 toString() 方法狗准,格式 person(age=18, name=ivy)
  • 4 copy()拷貝功能

8. 靜態(tài)變量克锣、靜態(tài)方法

kotlin中,沒有靜態(tài)方法的說法腔长。都是通過伴生對象companion object來實(shí)現(xiàn)袭祟。使用靜態(tài)變量可以通過
const val staticName: String ="123"來實(shí)現(xiàn)(必須寫在類的頂部),一般用于無法確定歸屬的全局變量捞附。但是最好使用伴生對象巾乳,對靜態(tài)變量歸類到所屬的類中。使用方法如下

class TestActivity{
  companion object{
        var username: String="ivy"
        fun startActivity(context: Context):Unit{
            val intent=Intent(context,KotlinHomeActivity::class.java)
            context.startActivity(intent)
        }
    }
}
//調(diào)用
TestActivity.companion.startActivity(context)

伴生對象并不是真正意義上的靜態(tài)變量鸟召,本質(zhì)也是一個(gè)對象

kotlin的單例寫法如下:

companion object{
        fun getUser() : String{
            return UserManager.user
        }

        private object UserManager{
            val user=User()
        }
    }

9. 泛型

kotlin的泛型和java的類似胆绊,有以下幾點(diǎn)不同:

  • 1 可以通過T::class來獲取到T的具體類型
  • 2 kotlin不支持通配符,即class person(? extends T)
  • 3 聲明處型變,即如下所示药版,只控制一個(gè)類中只有返回值才有可能需要校驗(yàn)T泛型辑舷,輸入是不會出現(xiàn)T泛型這種情況的(同時(shí)也有<in T>表示輸入)
abstract class Person<out T> {
  abstract fun getSomeThing(): T
}

那么這樣有什么好處呢?看下面的代碼槽片,這在java中不可行,是禁止這樣操作的肢础。但是實(shí)際上还栓,這樣是極為安全的

fun demo(strs: Person<String>) {
  val objects: Person<Any> = strs 
  // ...
}

10. 代理

kotlin當(dāng)中可以對類和屬性進(jìn)行代理

  • 1 代理類(代理模式)
interface Person{
  fun run()
}
class SuperMan() : Person{
  override fun run() { print("i can fly") }
}
class Delegate(person: Person) : Person by person
fun main(args: Array<String>) {
  val superMan = SuperMan()
  Delegate(b).run() //打印 i can fly"
}
  • 2 代理屬性,這是一個(gè)超級棒的功能传轰,這里面和很多功能剩盒,這里我就介紹兩種
  • 代理屬性
class Example {
  var p: String by Delegate()
}
class Delegate {
  operator fun getValue(thisRef: Any?, property: KProperty<*>): String {
    return 'someThing"
    }
operator fun setValue(thisRef: Any?, property: KProperty<*>, value: String) {
    println("value'")
   }
}

這個(gè)這可以在屬性獲取值和設(shè)置值的時(shí)候進(jìn)行代理攔截,這個(gè)功能非常強(qiáng)大慨蛙,例子如下 (代碼來源《Kotlin for Android Developer》

class Preference<T>(val context: Context, val name: String, val default: T, val prefName: String = "default") : ReadWriteProperty<Any?, T> {
    val prefs by lazy { context.getSharedPreferences(prefName, Context.MODE_PRIVATE) }
    override fun getValue(thisRef: Any?, property: KProperty<*>): T {
        return findPreference(name, default)
    }
    override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
        putPreference(name, value)
    }
    private fun <U> findPreference(name: String, default: U): U = with(prefs) {
        val res: Any = when (default) {
            is Long -> getLong(name, default)
            is String -> getString(name, default)
            is Int -> getInt(name, default)
            is Boolean -> getBoolean(name, default)
            is Float -> getFloat(name, default)
            else -> throw IllegalArgumentException("This type can be saved into Preferences")
        }
        res as U
    }
    private fun <U> putPreference(name: String, value: U) = with(prefs.edit()) {
        when (value) {
            is Long -> putLong(name, value)
            is String -> putString(name, value)
            is Int -> putInt(name, value)
            is Boolean -> putBoolean(name, value)
            is Float -> putFloat(name, value)
            else -> throw IllegalArgumentException("This type can be saved into Preferences")
        }.apply()
    }
}

當(dāng)使用get方法時(shí)辽聊,會自動(dòng)從sharePreference當(dāng)中取,當(dāng)給變量設(shè)值的時(shí)候會自動(dòng)給把值存儲更新到sharePreference當(dāng)中期贫,可以像使用正常變量一樣使用sharePreference跟匆,使用方法如下:

class TestActivity : Activity(){
    var version: Int by Preference(this, "version", 1.0.0)
}
  • 可觀察屬性(observable properties
    這個(gè)的作用,是當(dāng)一個(gè)變量的值改變時(shí)通砍,會進(jìn)行通知玛臂,并告知舊值和新值烤蜕。這個(gè)在開發(fā)中就非常實(shí)用了,比如定位功能迹冤,可以判斷定位的值是否發(fā)生變化讽营,設(shè)置了定位信息,從而允許接下來的邏輯泡徙。
var locationCity: String by Delegates.observable("<no location>") {
        prop, old, new ->
        println("$old -> $new")
}

在開發(fā)中我們通常會通過 一個(gè)helper工具類來實(shí)現(xiàn)對某個(gè)對象的屬性值來進(jìn)行控制橱鹏。比如,當(dāng)設(shè)置的年齡小于15歲的時(shí)候不允許更改堪藐,在這里使用Delegates.observable()就很方便了莉兰,而且邏輯看起來更加清晰明了。
也可以通過Delegates.vetoable()來控制變量的值是否可以修改(使用方法和 Delegates.observable()一樣)

  • 3 屬性延遲
    在開發(fā)中庶橱,我們經(jīng)常會做一件事件贮勃,當(dāng)一個(gè)對象需要使用時(shí)才初始化,不使用不初始化苏章。這在kotlin中就很方便實(shí)現(xiàn)寂嘉,當(dāng)?shù)谝淮问褂脮r(shí)才初始化,隨后直接使用初始化后的值(該方法默認(rèn)是同步的枫绅,如果不需要同步可以加上LazyThreadSafetyMode.NONE)
val user:Student by lazy { 
        Student("girl",18,true)
}

11. 擴(kuò)展

kotlin的擴(kuò)展是我最喜歡的一個(gè)新功能了泉孩,之前開發(fā)ios的時(shí)候就喜歡得不得了,現(xiàn)在在Android中終于可以使用了并淋。在java世界中每個(gè)開發(fā)者都有一堆自己的工具類寓搬,如StringUtilsViewUtils县耽、ToastUtils等等句喷。但是這樣會有一個(gè)問題,比如View的一個(gè)工具類兔毙,誰知道你的工具類名叫什么?就算知道唾琼,也很麻煩。比如設(shè)置paddlingLeft的一般套路
ViewUtils.setPaddingLeft(view,paddingLeft)
但是通過擴(kuò)展澎剥,就完成清晰明了锡溯,和調(diào)系統(tǒng)方法沒有任務(wù)區(qū)別,首先編寫一個(gè)擴(kuò)展

fun View.setPaddingLeft(paddingLeftNew: Int){
        setPadding(paddingLeftNew,paddingTop,paddingRight,paddingBottom)
}
//調(diào)用:
view.paddingLeft=12

是不是很贊Q埔Α<婪埂!擴(kuò)展功能非常強(qiáng)大叙量,我們可以把各種工具類進(jìn)行簡化倡蝙。比如Toast

    fun Any.toast(text: String){
        Toast.makeText(applicationContext,text,Toast.LENGTH_SHORT).show()
    }

當(dāng)然擴(kuò)展不止于此,腦洞有多大宛乃,擴(kuò)展就有多強(qiáng)悠咱!

12. 和ButterKnife say goodbye

每個(gè)Android的開發(fā)者曾經(jīng)都為findViewById()而煩惱不已蒸辆,直到后來ButterKnife的出現(xiàn)。但是ButterKnife是不是就完美了析既,并不是躬贡!當(dāng)布局復(fù)雜的時(shí)候,activity里面前面一堆View的變量眼坏。那有沒有辦法去掉這一堆變量拂玻,有!

import kotlinx.android.synthetic.main.activity_kotlin.*
class Activity{
    btnCommint.text="xxx"
 }

activity_kotlin.xml

 <Button
        android:id="@+id/btnCommit"
        android:layout_width="match_parent"
        android:layout_height="40dp"
        android:text="i am kotlin button"/>

只需要把import布局文件宰译,就可以直接把Id當(dāng)成變量來使用檐蚜。輕輕松松和ButterKnife say goodbye宝踪。

13. 一些小細(xì)節(jié)

  • 1Class對象的獲取
View::class.java //在kotlin中獲取class對象傳遞到j(luò)ava代碼中
View::javaClass //在kotlin中獲取class對象傳遞到kotlin代碼中
  • 2 this的使用
class KotlinActivity{
  fun isBigNum(num: Int){

  }
  inner class Person{
        open fun run(){
            this@Person.run()
            this@KotlinActivity.isBigNum(3)
        }
    }
}
  • 3 SmartCast(類型轉(zhuǎn)換)
    java:
TextView view=(TextView)findViewById(R.id.tv)

kotlin:

var view=findViewById(R.id.tv) as TextView
  • 4 字符串拼接
    java:
System.out.println("username:"+user.getUsername()+"--age:"+age)

kotlin:

print("username:${user.username}--age:$age)
  • 5 三目運(yùn)算符
    kotlin當(dāng)中沒有三目運(yùn)算符钮蛛,實(shí)現(xiàn)三目運(yùn)算符的方法:
var maxValue= if(a>b) a else b
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末初斑,一起剝皮案震驚了整個(gè)濱河市跋选,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌谆吴,老刑警劉巖踩晶,帶你破解...
    沈念sama閱讀 218,640評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件砰粹,死亡現(xiàn)場離奇詭異蛛淋,居然都是意外死亡咙好,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,254評論 3 395
  • 文/潘曉璐 我一進(jìn)店門褐荷,熙熙樓的掌柜王于貴愁眉苦臉地迎上來勾效,“玉大人,你說我怎么就攤上這事叛甫〔愎” “怎么了?”我有些...
    開封第一講書人閱讀 165,011評論 0 355
  • 文/不壞的土叔 我叫張陵其监,是天一觀的道長卒密。 經(jīng)常有香客問我,道長棠赛,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,755評論 1 294
  • 正文 為了忘掉前任膛腐,我火速辦了婚禮睛约,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘哲身。我一直安慰自己辩涝,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,774評論 6 392
  • 文/花漫 我一把揭開白布勘天。 她就那樣靜靜地躺著怔揩,像睡著了一般捉邢。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上商膊,一...
    開封第一講書人閱讀 51,610評論 1 305
  • 那天伏伐,我揣著相機(jī)與錄音,去河邊找鬼晕拆。 笑死藐翎,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的实幕。 我是一名探鬼主播吝镣,決...
    沈念sama閱讀 40,352評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼昆庇!你這毒婦竟也來了末贾?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,257評論 0 276
  • 序言:老撾萬榮一對情侶失蹤整吆,失蹤者是張志新(化名)和其女友劉穎拱撵,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體掂为,經(jīng)...
    沈念sama閱讀 45,717評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡裕膀,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,894評論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了勇哗。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片昼扛。...
    茶點(diǎn)故事閱讀 40,021評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖欲诺,靈堂內(nèi)的尸體忽然破棺而出抄谐,到底是詐尸還是另有隱情,我是刑警寧澤扰法,帶...
    沈念sama閱讀 35,735評論 5 346
  • 正文 年R本政府宣布蛹含,位于F島的核電站,受9級特大地震影響塞颁,放射性物質(zhì)發(fā)生泄漏浦箱。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,354評論 3 330
  • 文/蒙蒙 一祠锣、第九天 我趴在偏房一處隱蔽的房頂上張望酷窥。 院中可真熱鬧,春花似錦伴网、人聲如沸蓬推。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,936評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽沸伏。三九已至糕珊,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間毅糟,已是汗流浹背红选。 一陣腳步聲響...
    開封第一講書人閱讀 33,054評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留留特,地道東北人纠脾。 一個(gè)月前我還...
    沈念sama閱讀 48,224評論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像蜕青,于是被迫代替她去往敵國和親苟蹈。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,974評論 2 355

推薦閱讀更多精彩內(nèi)容