Kotlin學(xué)習(xí)筆記

項目未來可能需要使用kotlin開發(fā),所以特此記錄一下學(xué)習(xí)筆記,僅供參考,方便后期查詢。已同步到GitHub上:KotlinTest

Kotlin 簡介

kotlin 的目標(biāo)是成為一門全棧語言,主要有以下的特點:

  • 已經(jīng)成為Android的官方推薦語言
  • 百分百的和java兼容,兩者可以相互轉(zhuǎn)換
  • JSJVMNative多平臺開發(fā)

數(shù)據(jù)類型

1. 基本類型

Boolean true/false
Double 64
Float  32
Long   64
Int    32
Short  32
Byte   8

val aChar = '0'
val bChar = '我'
val cChar = '\u000f'

Char類型的轉(zhuǎn)義字符

\t          制表符
\b          光標(biāo)后退一個字符
\n          回車
\r          光標(biāo)回到行首
\'          單引號
\"          雙引號
\\          反斜杠
\$          美元符號,Kotlin 支持美元符號開頭的字符串模板

2. 基本類型的轉(zhuǎn)換

不可隱式轉(zhuǎn)換

val anInt: Int = 5
val aLong: Long = anInt.toLong()

必須得通過.to類型的方式進行數(shù)據(jù)的轉(zhuǎn)換

字符串

  • 一串Char

  • 用雙引號""引起來

    val aString: String = "Hello World!"

  • 字符串比較

    a == b 表示比較內(nèi)容 類似 Java 中的 equals
    a === b 表示比較對象是否相同

  • 字符串模板

    println("hello, $name") -> "hello, 小明"

3. Koltin 中的類和對象初始化

類的定義

  • 類,一個抽象的概念
  • 具有某些特征的事物的概括
  • 不特定指代任何一個具體的事物

一般寫法:

/**
* 其中類參數(shù)如果加上 var 修飾,那么他便是成員變量,反之則是普通的參數(shù)
*/
class Student(var name: String, var age: Int){
    init {
        // ... 相當(dāng)于構(gòu)造函數(shù)中的代碼
    }
}

對象

  • 是一個具體的概念,與類相對

  • 描述某一個類的具體個體

  • 舉例:

    某些人、領(lǐng)導(dǎo)的車等等

類和對象的關(guān)系

  • 一個類通常可以有很多歌具體的對象
  • 一個對象本質(zhì)上只能從屬一個類
  • 某一個人,他是工程師,但本質(zhì)上還是屬于人這一類

一般寫法:

val student: Student = Student("xiaweizi", 23)

類的繼承

  • 提取多個類的共性得到一個更為抽象的類,即父類
  • 子類擁有父類的一切特征
  • 子類也可以定義自己的特征
  • 所有的類最終繼承自Any,類似于java中的Object

4. 空類型和智能轉(zhuǎn)換

空類型

// 定義
val notNull: String = null // 錯誤,不可能為空
val nullanle: String? = null // 正確,可以為空
// 使用
notNull.length // 正確,不可能為空所以可以直接使用
nullable.length // 有可能為空,不能直接獲取長度
// 要想獲取長度,可以通過以下兩者方式
nullable!!.length // 正確,強制認定 nullable 不可能為空,如果為空則會拋出空指針異常
nullable?.length // 正確,若 nullable 為空,則返回 null

智能類型轉(zhuǎn)換

val child: Child = parent as Child // 類似于 Java 的類型轉(zhuǎn)換,失敗則拋出異常
val child: Child = parent as? Child // 如果轉(zhuǎn)換失敗,返回 null

編譯器智能識別轉(zhuǎn)換:

val parent: Parent = Child()
if (parent is Child) {
    // parent 直接調(diào)用子類方法,不需要再進行強制轉(zhuǎn)換
}

val string: String = null
if (string != null) {
    // string.length 可以直接調(diào)用length 方法
}

5. 區(qū)間

一個數(shù)學(xué)上的概念,表示范圍, ClosedRange的子類,IntRange最常用

基本用法:

0..100 --> [0, 100]
0 until 100 --> [0, 100)
i in 0..100 表示 i 是否在區(qū)間[0, 100]中

6. 數(shù)組

基本寫法:

val ints: IntArray = IntArrayOf(1,2,3,5)
var charArray: CharArray = charArrayOf('a', 'b', 'c', 'd', 'e')
var stringArray: Array<String> = arrayOf("aa", "bb", "cc", "dd", "e")

基本操作:

print(charArray[index])
ints[0] = 2
ints.length
cahrArray.joinToString("") // 講 char 數(shù)組轉(zhuǎn)換成字符串
stringArray.slice(1..4) // 取出區(qū)間里的值

程序結(jié)構(gòu)

1. 常亮和變量

常量

val a = 2
類似 Java 中的 final
不可被重復(fù)賦值
運行時常量:val x = getX()
編譯期常量:const val x = 2

變量

var a = 2
a = 3 // 可以被再次賦值

類型推導(dǎo)

val string = "Hello" // 推導(dǎo)出 String 類型
val int = 5 // 推導(dǎo)出 Int 類型
var x = getString() + 5 // String 類型

2. 函數(shù) Function

以特定功能組織起來的代碼塊

// 最簡單的打印信息,無返回的方法
fun printMessage(message: String):Unit{
    println("$message")
}
// 擁有返回值得方法
fun sum(first: Int, second: Int):Int {
    return first + second
}
// 可以簡化成:
fun sum(first: Int, second: Int) = first + second
// 或者更簡單的匿名函數(shù)
val result = fun(first: Int, second: Int) = first + second

3. Lambda 表達式

其實又是匿名函數(shù)

一般形式

{傳入?yún)?shù) -> 函數(shù)體,最后一行是返回值}
// 例如
val sum = {first: Int, second: Int -> first + second}
val printMessage = {message: String -> println(message)}

類型標(biāo)識

() -> Unit // 無參,返回值為 null
(Int) -> Int // 傳入整型,返回一個整型
(String, (String) -> String) -> Boolean // 傳入字符串、Lambda 表達式,返回Boolean

Lambda 表達式的簡化

  • 函數(shù)參數(shù)調(diào)用時最后一個Lambda可以移出去
  • 函數(shù)參數(shù)只有一個Lambda,調(diào)用時小括號可以省略
  • Lambda只有一個參數(shù)可默認為it
  • 入?yún)ⅰ⒎祷刂蹬c形參一致的函數(shù)可以用函數(shù)引用方式作為實參傳入

4. 成員變量和成員方法

成員變量的聲明

// 第一種是在構(gòu)造函數(shù)中聲明
class Student(var age: Int, name: String){
    // age 是成員變量 name 是局部變量
}
// 第二種是在函數(shù)體內(nèi)聲明
var a = 0
    get() {
        field += 1
        return field
    }
    set(value) {
        println("set)
        field = value + 1
    }
// 可以進行對 get 和 set 方法的重新定義

// 屬性的初始化盡量在構(gòu)造方法中完成
// var 用 lateinit 延遲初始化, val 用 lazy

lateinit var sex: String
val person: Person by lazy {
    Person()
}

成員方法

在類中直接聲明方法可以直接調(diào)用,包括lambda表達式

// 方法的聲明
fun sum(a: Int, b: Int) = a + b
val sum1 = {a: Int, b: Int -> a + b}
// 方法的調(diào)用
println(person.sum(1,2))
println(person.sum1(3,5))

5. 運算符

java中運算符是不能重新定義重載的,只能按照原先的邏輯進行計算

Kotlin則可以重新定義運算符,使用operator關(guān)鍵字,舉了例子:

// 定義一個用于計算復(fù)數(shù)的類
class Complex(var real: Double, var imaginary: Double) {
    operator fun plus(other: Complex): Complex{
        return Complex(real+other.real, imaginary+other.imaginary)
    }
    
    // 重新 toString 方法
    overrride fun toString(): String {
        return "$real + ${imaginary}i"
    }
}
// 使用
val complex1 = Complex(1, 2)
val complex2 = Complex(2, 3)
println(complex1 + complex2)
// 輸出結(jié)果為
"3 + 5i"

關(guān)鍵就是這個方法,方法名必須是plus或者其他官方定義的運算符,參數(shù)有且僅有一個,類型自定義,返回值意識可以自定義的.

operator fun plus(other: Complex): Complex{
        return Complex(real+other.real, imaginary+other.imaginary)
}

6. 表達式

中綴表達式

通過infix關(guān)鍵字修復(fù)方法,那么就可以不用通過 對象.方法() 的方式調(diào)用,而是直接 對象 方法名 參數(shù)的方式調(diào)用。舉了例子

class Student(var age: Int){
    infix fun big(student: Student): Boolean {
        return age > student.age
    }
}
// 如果沒有 infix 的調(diào)用方式:
println(Student(23).big(Student)(12))
// 如果使用 infix 修飾的調(diào)用方式:
println(Student(23) big Student(12))

if表達式

直接來個例子

val a = 20
val b = 30
val flag: Int = if(a > b) a else b

When 表達式

加強版的 switch,支持任意類型, 支持純粹表達式條件分支(類似if),舉個栗子:

val a = 5
when(a) {
    is Int -> println("$a is Int")
    in 1..6 -> println("$a is in 1..6")
    !in 1..4 -> println("$a is not in 1..4")
    else -> {
        println("null")
    }
}

for循環(huán)

基本寫法

for (element in elements)

while循環(huán)

基本寫法

while() {
}
do {
} while()

跳過和終止循環(huán)

跳過當(dāng)前循環(huán)用 continue
終止循環(huán)用 break

6. 異常捕獲

同樣也是表達式,可以用來賦值,舉個例子

return try{
            x/y
        }
        catch(e: Exception) {
            0
        } finally {
            //...
        }

如果沒有異常則返回x/y,否則返回0,finally中的代碼無論如何還是要執(zhí)行的。

7. 具名參數(shù)、變長參數(shù)和默認參數(shù)

具名參數(shù):給函數(shù)的實參附上形參

fun sum(first: Int, second: Int) = first + second
sum(second = 2, first = 1)

變長參數(shù):varary修飾,使用起來是和數(shù)組一樣,某個參數(shù)可以接收多個值,可以不作為最后一個參數(shù),如果傳參時有歧義,需要使用具名參數(shù)。

fun hello(vararg ints: Int, string: String) = ints.forEach(println(it))
hello(1,3,4,5,string = "hello")
// 如果最后一個參數(shù)也是 Int
fun hello(varary ints: Int, anInt: Int)
// 創(chuàng)建數(shù)組
val arrayInt: IntArray = intArrayOf(1, 2, 3, 4)
hello(ints = *arrayInt, anInt = 2)

默認參數(shù):就是給參數(shù)傳入一個默認的值

fun hello(anInt: Int = 1, string: String)
hello(string = "aaa")

面向?qū)ο?/h2>

1. 繼承

繼承語法要點:

  • 父類需要open才可以被繼承
  • 父類方法、屬性需要open才可以被覆寫
  • 接口、接口方法、抽象類默認為open
  • 覆寫父類(接口)成員需要override關(guān)鍵字

語法要點:

  • class A: B(), C, D
  • 繼承類時實際上調(diào)用了父類的構(gòu)造方法
  • 類只能單繼承,接口可以多實現(xiàn)

接口代理:

一個類可以直接將自己的任務(wù)委托給接口的方法實現(xiàn),舉個例子:

interface Drive{
    fun drive()
}

interface Sing{
    fun sing()
}

class CarDrive: Drive{
    override fun drive() {
        println("我會開車呦")
    }
}

class LoveSing: Sing{
    override fun sing() {
        println("我會唱歌呦")
    }
}

class Manager(drive: Drive, sing: Sing): Drive by drive, Sing by sing

fun main(args: Array<String>) {
    val carDrive = CarDrive()
    val loveSing = LoveSing()
    val manager = Manager(carDrive, loveSing)
    manager.drive()
    manager.sing()
}

這樣,manager不用做任何事情,完全交付給接口實現(xiàn).

接口方法沖突:

接口方法可以有默認實現(xiàn),通過super<父類名>.方法名

interface A{
    fun a() = 0
}

interface B{
    fun a() = 1
}

interface C{
    fun a() = 2
}

class D(var aInt: Int): A,B,C{
    override fun a(): Int {
        return when(aInt){
            in 1..10 ->{
                super<A>.a()
            }
            in 11..100 ->{
                 super<B>.a()
             }
            else -> {
                println("dd")
                super<C>.a()
            }
        }
    }
}

2. 類及成員的可見性

java類似,private、protected、public,其中internal代表的是模塊內(nèi)可見

3. Object

相當(dāng)于Java中的單例模式,有以下特點

  • 只有一個實例的類

  • 不能自定義構(gòu)造方法

  • 可以實現(xiàn)接口、繼承父類

  • 本質(zhì)上就是單例模式最基本的實現(xiàn)

      interface getDataSuccess{
          fun success()
      }
      
      abstract class getDataField{
          abstract fun failed()
      }
      
      object NetUtil: getDataField(), getDataSuccess{
          override fun success() {
              println("success")
          }
      
          override fun failed() {
              println("failed")
          }
      
          val state: Int = 0
          fun getData(): String = "請求成功"
      }
    

3. 伴生對象和靜態(tài)成員

相當(dāng)于java中的靜態(tài)方法

  • 每個類可以對應(yīng)一個伴生對象

  • 伴生對象的成員全局獨一份

  • 如果java中想直接調(diào)用kotlin中的靜態(tài)方法或者靜態(tài)變量,可以考慮使用JvmField JvmStatic.

      open class Util private constructor(var anInt: Int) {
          companion object {
              @JvmStatic
              fun plus(first: Int, second: Int) = first + second
      
              fun copy(util: Util) = Util(util.anInt)
              @JvmField
              val tag = "tag"
          }
      }
    

4. 方法的重載

通過給方法的參數(shù)配置默認值,即可實現(xiàn)方法的重載,按理說,一切可以擁有默認值的方法重載才是合理的方法重載。

名稱形同、參數(shù)不同,跟返回值沒有關(guān)系

class OverLoadTest {
    @JvmOverLoads
    fun a(anInt: Int = 0, string: String="") = 1
}

val test = OverLoadTest()
test.a(1, "")
test.a()
test.a(anInt = 2)
test.a(string = "")

使用JvmOverLoads是為了方便Java中調(diào)用方法的重載.

5. 擴展方法

kotlin中的擴展方法,我認為相當(dāng)于java中的代理模式,拿到被代理的對象,然后進行一系列的操作。

fun String.add(anInt: Int): String {
    var sb = StringBuilder()
    for (i in 0 until anInt) {
        sb.append(this)
    }
    return sb.toString()
}

operator fun String.times(anInt: Int): String {
    var sb = StringBuilder()
    for (i in 0 until anInt) {
        sb.append(this)
    }
    return sb.toString()
}

// 使用
var string = "xiaweizi"
println(string.add(5))
println(string * (3))

6. 屬性代理

類似之前說的var anInt: Int by lazy{2},懶賦值就是使用的屬性代理,來看個例子:

fun main(args: Array<String>) {
    val a: Int by DelegatesTest()
    println(a)

    var b: Int by DelegatesTest()
    b = 3
    println(b)
}

class DelegatesTest {
    private var anInt: Int? = null
    operator fun getValue(thisRef: Any?, property: KProperty<*>): Int {
        println("getValue")
        return anInt?:0
    }

    operator fun setValue(thisRef: Any?, property: KProperty<*>, value: Int): Unit {
        println("setValue")
        this.anInt = value
    }
}

val 對應(yīng) getValuevar對應(yīng)getValue和setValue方法,這個時候聲明的屬性就全權(quán)交付給DelegatesTest類中的anInt代理,當(dāng)anInt為空的時候返回0,否則返回anInt.

7. JavaBean

使用data修飾類,類似java中的javaBean,默認實現(xiàn)了set get toString等方法,并擁有componentN方法.

不過有個缺點就是,無法被繼承,沒有無參構(gòu)造函數(shù),可以通過安裝allOpennoArg插件解決這個問題.

data class UserBean(var name: String, var age: Int)

val userBean: UserBean = UserBean("小芳", 23)
println(userBean.name)
println(userBean.toString())

println(userBean.component1())
println(userBean.component2())

val (name, age) = userBean
println("name: $name")
println("age: $age")

至于這種寫法val (name, age) = userBean,是因為定義了component1的運算符

class Complex{
    operator fun component1() = "你好呀"
    operator fun component2() = 2
    operator fun component3() = 'a'
}

val complex = Complex()
val (a, b, c) = complex
println(a + b + c)

使用起來也是很簡單的

8. 內(nèi)部類

  • 定義在類內(nèi)部的類
  • 與類成員有相似的訪問控制
  • 默認是靜態(tài)內(nèi)部類,非靜態(tài)用 inner 關(guān)鍵字
  • this@Outter this@Inner 的用法
  • 匿名內(nèi)部類
    • 沒有定義名字的內(nèi)部類
    • 類名編譯時生成,類似Outter$1.class
    • 可繼承父類,實現(xiàn)多個接口,與Java注意區(qū)別

舉個例子:

class Outer{
    var string: String = "outer"
    class Inner1{
        var string: String = "inner1"
        fun sum(first: Int, second: Int) = first + second
    }

    inner class Inner2{
        var string: String = "inner2"
        fun cha(first: Int, second: Int) = first - second
        fun getInnerField() = this.string
        fun getOuterField() = this@Outer.string
    }
}

fun main(args: Array<String>) {
    val inner1 = Outer.Inner1()
    val inner2 = Outer().Inner2()

    println(inner1.sum(1, 2))

    println(inner2.cha(2, 1))
    println(inner2.getInnerField())
    println(inner2.getOuterField())
}

匿名內(nèi)部類:

val listener: onClickListener = object : Father(), Mother, onClickListener{
    override fun sing() {
        println("mother sing")
    }

    override fun teach() {
        println("father teach")
    }

    override fun onClick() {
        println("匿名內(nèi)部類")
    }
}

使用Object實現(xiàn)匿名內(nèi)部類

9. 枚舉和密封類

枚舉是對象可數(shù),每個狀態(tài)相當(dāng)于每個對象,是可以傳構(gòu)造參數(shù)的

密封類時子類可數(shù),在kotlin大于1.1子類只需要與密封類在同一個文件加,保護子類的位置

sealed class SealedClassTest{
    class sum(first: Int, seocnd: Int): SealedClassTest()
    class cha(first: Int, seocnd: Int): SealedClassTest()

    object Bean: SealedClassTest()
}

enum class HttpStatus(val anInt: Int){
    SUCCESS(0), FAILED(1), LOADING(2)
}

fun main(args: Array<String>) {
    val class1 = SealedClassTest.cha(1, 2)
    println(HttpStatus.SUCCESS)
}

高階函數(shù)

1. 基本概念

  • 傳入或者返回函數(shù)的函數(shù)
  • 函數(shù)引用 ::println
  • 帶有Receiver的引用 pdfPrinter::println

有三種顯示

// 1. 包級函數(shù)
intArray.forEach(::print)

// 2. 類.方法
intArray.forEach(Int::addOne)
fun Int.addOne(): Unit {
    println("addOne:$this")
}

// 3. 對象.方法
intArray.forEach(AddTwo()::addTwo)
class AddTwo {
    fun addTwo(anInt: Int): Unit {
        println("addTwo:$anInt")
    }
}

2. 常用的高階函數(shù)

常用的高階函數(shù)還是有很多的,會簡單的使用例子即可:

// 遍歷
fun forEachTest() {
    val strings: Array<String> = arrayOf("aa", "ee", "bb", "ll")

    strings.forEach { println(it) } // 遍歷每一個值
    strings.forEachIndexed { index, s -> println("index:$index,String:$s") } // 遍歷 下標(biāo)和值一一對應(yīng)

}

// 重新拷貝一個值
fun mapTest() {
    val strings: Array<String> = arrayOf("aa", "ee", "bb", "ll")
    var map = strings.map { "$it-test" }
    map.forEach { print("$it\t") }
}

// 將集合合體
fun flatMapTest() {
    val lists = listOf(1..10,
            2..11,
            3..12)

    var flatMap = lists.flatMap {
        it.map {
            "No.$it"
        }
    }
    flatMap.forEach(::println)
}

fun reduceTest() {
    val ints = listOf(2, 3, 4, 5)
    println(ints.reduce { acc, i ->
        acc + i
    })
}

// 字符串連接
fun foldTest(){
    val ints = listOf(2, 3, 4, 5)
    println(ints.fold(StringBuffer(), { acc, i -> acc.append("$i,") }))
    println(ints.joinToString(","))
}

fun filterTest() {
    val ints = listOf(1, 2, 3, 4, 5, 6)
    println(ints.filter { element -> element % 2 == 0 })
}

// 當(dāng)值不是奇數(shù)就去,遇到偶數(shù)就停止了
fun takeWhileTest() {
    val ints = listOf(1, 3, 3, 4, 5, 6)
    println(ints.takeWhile { it % 2 != 0 })
}

fun letTest() {
    findPerson()?.let { (name, age) -> println("name:$name, age:$age") }
    findPerson()?.apply { println("name:$name, age:$age") }
    with(findPerson()!!) { println("name:$name, age:$age") }
}

data class Person(val name: String, val age: Int)

fun findPerson(): Person? {
    return Person("aa", 23)
}

3. 復(fù)合函數(shù)

有點類似數(shù)據(jù)中的f(g(x))

fun main(args: Array<String>) {
    val add1 = {int: Int ->
        println("add1")
        int + 1}
    val add2 = {int : Int ->
        println("add2")
        int + 2}
    var add3 = add1 addThen (add2)
    println(add3(4))
}


infix fun <P1, P2, R> Function1<P1, P2>.addThen(function: Function1<P2, R>): Function1<P1, R> {
    return fun(p: P1): R{
        return function.invoke(this.invoke(p))
    }
}

4. Currying

簡單來說就是多元函數(shù)變換成一元函數(shù)調(diào)用鏈式,舉個簡單的例子,這是優(yōu)化之前:

fun log(tag: String, out: OutputStream, message: String){
    out.write("[$tag], $message".toByteArray())
}

優(yōu)化之后

fun log(tag: String)
    = fun(out: OutputStream)
    = fun(message: String)
    = out.write("[$tag], $message".toByteArray())

5. 計算文件字符串個數(shù)的小例子

首先將字符串轉(zhuǎn)換成字符串?dāng)?shù)組:

val map: HashMap<Char, Int> = HashMap()
var toCharArray = File("build.gradle").readText().toCharArray()

通過分組的方式,統(tǒng)計每個字符串的個數(shù),并打印:

toCharArray.groupBy { it }.map { it.key to  it.value.size }.forEach { println(it) }

kotlinjava的混合開發(fā)

1. 基本的交互操作

屬性讀寫

  • Kotlin自動識別 Java Getter/Setter
  • Java操作Kotlin屬性通過Getter/Setter

空安全類型

  • Kotlin空安全類型的原理
  • 平臺類型Platform Type
  • Java可以通過@Nullable、@NotNull

幾類函數(shù)的調(diào)用

  • 包級函數(shù):靜態(tài)方法
  • 擴展方法:帶Receiver的靜態(tài)方法
  • 運算符重載:帶Receiver的對應(yīng)名稱的靜態(tài)方法

幾個常用的注解

  • @JvmField:將屬性編譯為Java變量
  • @JvmStatic:將對象的方法編譯成功Java靜態(tài)方法
  • @JvmOverloads:默認參數(shù)生成重載方法
  • @JvmName:制定Kotlin文件編譯后的類名

NoArg 和 AllOpen

  • NoArg為被標(biāo)注的類生成無參構(gòu)造
  • AllOpen為被標(biāo)注的類去掉final,允許被繼承

正則表達式

  • Raw字符串定義正則表達式
  • JavaPattern
  • KotlinRegex

舉個例子:

val source = "Hello This my phone number: 010-12345678."
val pattern = """.*(\d{3}-\d{8}).*"""

Regex(pattern).findAll(source).toList().flatMap(MatchResult::groupValues).forEach(::print)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 230,578評論 6 544
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,701評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,691評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,974評論 1 318
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 72,694評論 6 413
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 56,026評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 44,015評論 3 450
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 43,193評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,719評論 1 336
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 41,442評論 3 360
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,668評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,151評論 5 365
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,846評論 3 351
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,255評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,592評論 1 295
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,394評論 3 400
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 48,635評論 2 380

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