Swift5.0 - day4-閉包玷坠、屬性、方法劲藐、下標(biāo)

一八堡、閉包

  • 1.1、閉包表達(dá)式(Closure Expression)
    在 Swift 里面可以通過函數(shù) func 定義一個函數(shù)聘芜,也可以通過閉包表達(dá)式定義一個函數(shù)

    func sum(_ v1:Int,_ v2:Int) -> Int{
    
       return v1+v2
    }
    sum(1,2) // 3
    

    閉包的格式

    {    參數(shù)列表  -> 返回值類型 in
           具體的代碼
    }
    

    閉包的具體舉例

    var fn = {
    
        (_ v1:Int,_ v2:Int) -> Int in
    
        return v1+v2
    }
    
    fn(2,3)    // 5
    

    提示:上面僅僅是給閉包定義了一個變量秕重,如果不寫變量和下面的意思一樣

    { 
       (_ v1:Int,_ v2:Int) -> Int in
    
        return v1+v2
    }(2,3)
    
  • 1.2、閉包表達(dá)式的簡寫
    基礎(chǔ)的閉包

    var fn = {
    
      (v1:Int,v2:Int) -> Int in
    
         return v1+v2
    }
    

    簡寫的代碼

    func exec(v1:Int,v2:Int,fn:(Int,Int)->Int){
      
       print(fn(v1,v2))
    }
    

    提示:傳進(jìn)去一個閉包

    調(diào)用 exec 函數(shù)方式如下:等效厉膀,結(jié)果都是 20
    方式一

    exec(1, 2, fn: fn)
    

    方式二

    exec(v1: 10, v2: 10) { (v3, v4) -> Int in
         return v3 + v4
    }
    

    方式三

    exec(v1: 10, v2: 10, fn: {
           v3,v4 in return v3+v4
    })
    

    方式四

    exec(v1: 10, v2: 10, fn: {
           v3,v4 in v3+v4
    })
    

    方式五

    exec(v1: 10, v2: 10, fn: {$0 + $1})
    

    方式六

    exec(v1: 10, v2: 10, fn: +)
    
  • 1.3溶耘、尾隨閉包

    • 如果將一個很長的閉包表達(dá)式作為函數(shù)的最后一個實(shí)參,使用尾隨閉包可以增強(qiáng)函數(shù)的可讀性

    • 尾隨閉包是一個被書寫在函數(shù)調(diào)用括號外面(后面)的閉包表達(dá)式

      func exec(v1:Int,v2:Int,fn:(Int,Int)->Int){
      
           print(fn(v1,v2))
      }
      
      exec(v1: 6, v2: 7, fn: {$0 + $1})
      

      結(jié)果:13服鹅,讓兩個參數(shù)相加凳兵,我們還可以:-* 等等

    • 如果閉包表達(dá)式是函數(shù)的唯一實(shí)參企软,而且使用了尾隨閉包的寫法庐扫,那就不需要再函數(shù)名后面寫圓括號

      func exec(fn:(Int,Int)->Int){
      
             print(fn(2,5))
      }
      

      調(diào)用方式如下,結(jié)果為 7

      exec(fn: {$0 + $1})   
      exec(){$0 + $1}
      exec{$0 + $1}
      
  • 1.4、數(shù)組的排序

    func cmp(i1:Int,i2:Int) -> Bool {
         // 大的排到前面
         return i1 > i2
    }
    // 返回 false: i1 排在 i2 后面形庭,也就是 i1 的值小于 i2
    // 返回 true: i1 排在 i2 前面铅辞,也就是 i1 的值大于 i2
    
  • 1.5、忽略參數(shù)

    func exec(fn:(Int,Int)->Int){
         print(fn(1,5))
    }
    exec{_,_ in 11}  // 11
    
  • 1.6萨醒、閉包(Closure):的實(shí)質(zhì)是一段有具體功能的代碼塊斟珊。

    • 閉包:一個函數(shù)和他捕獲的變量/常量環(huán)境組合起來,稱為閉包富纸。閉包的核心是在其使用的局部變量/常量 會被額外的復(fù)制或者引用囤踩,使這些變量脫離其作用域后依然有效。
      • 一般指定義在函數(shù)內(nèi)部的函數(shù)

      • 一般它捕獲的是外層函數(shù)的局部變量/常量

        // 返回的 plus 與 num 形成了閉包
        func getFn() -> Fn{
        
             var num = 0
             func plus(_ i:Int) -> Int{
        
                 num += I
                 return num
             }
        
             return plus
        }
        
        var fn1 = getFn()
        var fn2 = getFn()
        
        fn1(1)
        fn2(2)
        
    • 可以把閉包想象成一個類的實(shí)例對象
      • 存儲在堆空間

      • 捕獲的局部變量/常量就是對象的成員(存儲屬性)

      • 組成閉包的函數(shù)就是類內(nèi)部定義的方法

        class Closure{
        
            var num = 2
            func plus(_ i:Int) -> Int {
                 num += I
                 return num
            } 
        }
        
        var cs1 = Closure()
        var cs2 = Closure()
        
        cs1.plus(2)   // 4
        cs2.plus(2)   // 4
        
        cs1.plus(3)   // 7
        cs2.plus(3)   // 7
        
  • 1.7晓褪、自動閉包
    自動閉包的條件:自動閉包參數(shù)使用有嚴(yán)格的條件是首先此閉包不能有參數(shù)堵漱,其次在調(diào)用函數(shù)傳參的時,此閉包的實(shí)現(xiàn)只能由一句表達(dá)式組成涣仿,閉包的返回值即為此表達(dá)式的值勤庐,自動閉包由 @autoclosure 來聲明,如下 例三

    • 例一:如果第1個數(shù)大于0好港,返回第一個數(shù)埃元。否則返回第2個數(shù)

      func getFirstPositive(_ v1: Int, _ v2: Int) -> Int
      {
         return v1 > 0 ? v1 : v2 
      }
      getFirstPositive(10, 20)
      
    • 例二:改成函數(shù)類型的參數(shù),可以讓v2延遲加載

      func getFirstPositive(_ v1: Int, _ v2: () -> Int) -> Int?
      {
           return v1 > 0 ? v1 : v2()
      }
      getFirstPositive(-4) { 20 }
      
    • 例三:為了避免與期望沖突媚狰,使用了@autoclosure的地方最好明確注釋清楚:這個值會被推遲執(zhí)行

      func getFirstPositive(_ v1: Int, _ v2: @autoclosure () -> Int) -> Int? {
           return v1 > 0 ? v1 : v2()
      }
      
      getFirstPositive(-4, 20)
      
    • 結(jié)論

      • @autoclosure 會自動將 20 封裝成閉包 { 20 }
      • @autoclosure 只支持 () -> T 格式的參數(shù) @autoclosure并非只支持最后1個參數(shù)
      • 空合并運(yùn)算符 ?? 使用了@autoclosure 技術(shù)
      • @autoclosure岛杀、無@autoclosure,構(gòu)成了 函數(shù)重載
  • 1.8崭孤、逃逸閉包和非逃逸閉包

    • 逃逸閉包:是指函數(shù)內(nèi)的閉包在函數(shù)執(zhí)行結(jié)束后在函數(shù)外依然可以使用
    • 非逃逸閉包:是指在函數(shù)的聲明周期結(jié)束后类嗤,閉包也將會被銷毀。換句話說辨宠,非逃逸閉包只能在函數(shù)內(nèi)部使用遗锣,在函數(shù)外部不能使用。默認(rèn)情況下函數(shù)中的閉包都為非逃逸閉包嗤形,這樣做的優(yōu)點(diǎn)是可以提高代碼的性能精偿,節(jié)省內(nèi)存消耗,開發(fā)者可以根據(jù)實(shí)際需求將閉包參數(shù)聲明為逃逸閉包赋兵。

      提示:

      • 非逃逸閉包也不可以作為返回值返回笔咽,如果這么做,編譯器會拋出一個錯誤霹期。

      • 將閉包聲明為非逃逸型叶组,需要使用 @noescape 修飾。需要注意的是历造,在最新的Xcode版本里面已經(jīng)不需要再使用甩十,參數(shù)默認(rèn)都是非逃逸的船庇,如下代碼

        只有一個閉包的函數(shù),將此閉包聲明為非逃逸的侣监,此閉包既不可最為返回值也不可賦值給外部變量
        在xcode10.1中會有警告鸭轮,這個關(guān)鍵字可以忽略
        
        @noescape 默認(rèn)的,不需要單獨(dú)再寫
      • 逃逸類型的閉包通常用于異步操作中橄霉,例如一個請求完成后要執(zhí)行閉包回調(diào)窃爷,需要使用逃逸類型。

二酪劫、屬性

  • 2.1吞鸭、Swift 里面跟實(shí)例相關(guān)的屬性可以分為2大類

    • 存儲屬性(Sored Property)
      • 類似于成員變量這個概念
      • 存儲在實(shí)例的內(nèi)存中
      • 結(jié)構(gòu)體和類可以定義存儲屬性
      • 枚舉不可以定義存儲屬性

      提示:

      • 關(guān)于存儲屬性寺董,在Swift里面有個明確的規(guī)定覆糟,在創(chuàng)建類和結(jié)構(gòu)體的時候,必須為所有的存儲屬性設(shè)置一個合適的初始值遮咖。

        struct Circle {
             /// 存儲屬性
             var radius:Double
        }
        var circle = Circle(radius: 2)
        
      • 可以在初始化器里面為存儲屬性設(shè)置一個初始值

        struct Circle {
             /// 存儲屬性
             var radius:Double
             init () {
                 radius = 2
             }
        }
        var circle = Circle()
        
      • 可以分配一個默認(rèn)的屬性值作為屬性定義的一部分滩字。如在定義屬性的時候直接給一個 值,var radius:Int = 2

        struct Circle {
             /// 存儲屬性
             var radius:Double = 2.0
        }
        var circle = Circle()
        
    • 計(jì)算屬性(Computed Property)
      • 本質(zhì)就是方法(函數(shù))
      • 不占用實(shí)例的內(nèi)存
      • 枚舉御吞、結(jié)構(gòu)體麦箍、類 都可以定義計(jì)算屬性

      提示:

      • set傳入的新值默認(rèn)叫做 newValue,也可以自定義
      • 定義計(jì)算屬性只能用 var ,不能用 let(代表常量,值是一成不變的)
      • 計(jì)算屬性的值是可能發(fā)生變化的(即使是只讀計(jì)算屬性)
      • set方法的話必須有get方法陶珠,有get方法可以沒有set方法
  • 2.2挟裂、以結(jié)構(gòu)體舉例

    struct Circle {
           /// 存儲屬性
           var radius:Double
           /// 計(jì)算屬性
           var diameter:Double {
                set {
                    radius = newValue / 2.0
                }
                get {
                    radius * 2.0
                }
            }
    }
    
    var circle = Circle(radius: 2)
    circle.diameter = 20;
    //結(jié)果是 8 個字節(jié)
    print("占用的內(nèi)存大小=\(MemoryLayout.stride(ofValue: circle))") 
    

    提示:計(jì)算屬性是不占內(nèi)存的,原因是它的set 和 get 類似于兩個函數(shù)揍诽,如下代碼诀蓉,由此可以看出是不占用內(nèi)存的

    func setDiameter (newValue:Double) {
         radius = newValue / 2.0
    }
    func getDiameter (newValue:Double) -> Double {
         radius * 2.0
    }
    
  • 2.3、枚舉原始值 rawvalue 原理

    enum TestEnum : Int {
          case test1 = 1, test2 = 2, test3 = 3
          var rawValue: Int {
              switch self {
              case .test1:
                   return 8
              case .test2:
                   return 8
              case .test3:
                   return 10 
              }
          } 
    }
    print(TestEnum.test3.rawValue) // 結(jié)果 10
    

    枚舉原始值 rawValue 的本質(zhì)是:只讀計(jì)算屬性,查看匯編里面只有 get 方法

  • 2.4暑脆、延遲存儲屬性(Lazy Stored Property)

    • 使用 lazy 可以定義一個延遲存儲屬性渠啤,在第一次用到屬性的時候才會進(jìn)行初始化

      class Car {
          init() {
              print("Car init")
          }
          func run() {
              print("Car is running!")
          }
      }
      
      class Person {
          lazy var car = Car()
          init() {
              print("Person init")
          }
      
          func goOut() {
             car.run()
          }
      }
      // 使用
      let person = Person()
      print("------")
      person.goOut()
      

      打印結(jié)果如下:我們可以看到在 let person = Person()執(zhí)行的時候 lazy var car = Car()沒有立馬執(zhí)行,而是在用到 car 的時候才被調(diào)用的添吗,由此可以看出在存儲屬性前面加上 lazy 是不會立馬執(zhí)行的沥曹,在用到的時候才會被執(zhí)行

      Person init
      ------
      Car init
      Car is running!
      

      提示

      • lazy 屬性必須是 var,不能是let
      • let 必須在實(shí)例的初始化方法完成之前就擁有值
      • 如果 多條線程 同時第一次訪問 lazy 屬性碟联,是無法保證屬性只被初始化1次妓美,這個是線程不安全的
      lazy var image:UIImage = {
         //圖片url
         let imgUrl = "http://www.uw3c.com/images/index/logo_monkey.png"/
         let url : NSURL = NSURL(string:imgUrl)!// 轉(zhuǎn)換網(wǎng)絡(luò)URL
         let data : NSData = NSData(contentsOf:url as URL)!
         return UIImage(data: data as Data)!
      }()
      
  • 2.5、延遲屬性的注意點(diǎn)

    • 當(dāng)一個結(jié)構(gòu)體包含一個延遲屬性的時候鲤孵,只有 var 才能訪問延遲屬性部脚,因?yàn)檠舆t屬性初始化時需要改變結(jié)構(gòu)體的內(nèi)存

      解釋:如果實(shí)例定義為 let,那么節(jié)結(jié)構(gòu)體的內(nèi)存就固定了裤纹,不能被修改委刘,那么延遲屬性的本質(zhì)是修改結(jié)構(gòu)體的內(nèi)存丧没,編譯器就會直接報(bào)錯

      struct Point1 {
         var x = 1
         var y = 2
         lazy var z = 3
      }
      // 使用
      let point = Point1()
      point.z
      
  • 2.6、屬性觀察器

    struct Circle {
       /// 存儲屬性
       var radius:Double {
           willSet {
               print("willSet",newValue)
           }
      
           didSet {
               print("didSet",oldValue,radius)
           }
        }
        init() {
            self.radius = 1.0
            print("Circle init")
        }    
    }
    
    var circle = Circle()
    circle.radius = 10 
    print(circle.radius)
    打印結(jié)果如下
    Circle init
    willSet 10.0
    didSet 1.0 10.0
    10.0
    

    提示:

    • willSet 會傳遞新值锡移,默認(rèn)值叫 newValue
    • didSet 會傳遞舊值呕童,默認(rèn)值叫 oldValue
    • 在初始化器中設(shè)置屬性值不會觸發(fā) willSetdidSet
    • 在屬性定義時設(shè)置初始值也不會觸發(fā) willSetdidSet
  • 2.7、全局變量 和 局部變量

    • 屬性觀察器淆珊、計(jì)算屬性的功能夺饲,同樣可以應(yīng)用在全局變量,局部變量身上

    • 全局變量

      var num:Int {
           get {
               return 10
           }
           set {
               print("setNum",newValue)
           }
      }
      num = 12  // setNum 12
      print(num) // 10
      
    • 局部變量

      fun test() {
           var age:Int = 10 {
              willSet {
                  print("willSet",newValue)
              }
              didSet {
                  print("didSet",oldValue,radius)
              }
           }
           age = 11
           // 打邮┓:willSet 11
           // didSet 10 11
      }
      // 調(diào)用方法
      test()
      
  • 2.8往声、inout 本質(zhì)的探究

    struct Shape {
          var width:Int
          var side:Int {
              willSet {
                 print("willSet - side",newValue)
              }
              didSet {
                 print("willSet - side",oldValue,side)
              }
           }
           var girth:Int {
               set {
                  width = newValue / side
                  print("setGirth",newValue)
               }
               get {
                  print("getGirth")
                  return width * side
               }
            }
    
            func show() -> Void {
                print("width = \(width), side = \(side), girth = \(girth)")
            }
    }
    
    func test(_ num: inout Int) -> Void {
        num = 20
    }
    
    var s = Shape(width: 10, side: 4)
    test(&s.width)
    s.show()
    print("----------")
    test(&s.side)
    s.show()
    print("----------")
    test(&s.girth)
    s.show()
    打印結(jié)果是
    
    getGirth
    width = 20,side = 4,width = 80
    ----------
    willSet - side 20
    willSet - side 4 20
    getGirth
    width = 20,side = 20,width = 400
    ----------
    getGirth
    setGirth 20
    getGirth
    width = 1,side = 20,width = 20
    
    • 如果實(shí)參有物理內(nèi)存地址,且沒有設(shè)置屬性觀察器:直接將實(shí)參的內(nèi)存地址傳入函數(shù)(實(shí)參進(jìn)行引用傳遞)
    • 如果實(shí)參是計(jì)算屬性 或者 設(shè)置了屬性觀察器:采取了 Copy In Copy Out 的做法
      • 調(diào)用函數(shù)時戳吝,先復(fù)制實(shí)參的值浩销,產(chǎn)生副本 【get】
      • 將副本的內(nèi)存地址傳入函數(shù) (副本進(jìn)行引用傳遞),在函數(shù)的內(nèi)部可以修改副本的值
      • 函數(shù)返回后听哭,再將副本的值覆蓋實(shí)參的值 【set】
    • 總結(jié):inout 的本質(zhì)是引用傳遞 (地址傳遞)
  • 2.9慢洋、類型屬性(Type Property)
    嚴(yán)格來說屬性可以分為:實(shí)例屬性 和 類型屬性

    • 實(shí)例屬性(Instance Property):只能通過實(shí)例去訪問

      • 存儲實(shí)例屬性(Stored Instance Property):存儲在實(shí)例內(nèi)存中,每個實(shí)例都有一份內(nèi)存
      • 計(jì)算實(shí)例屬性(Computed Instance Property)
    • 類型屬性(Type Property):只能通過類去訪問

      • 存儲類屬性(Stored Instance Property):整個程序運(yùn)行中陆盘,就只有一份內(nèi)存(類似于全局變量)

      • 計(jì)算類屬性(Computed Instance Property)

      • 可以通過 static 定義類型屬性普筹,如果是類可以使用關(guān)鍵字 class

        struct Car {
             static var count = 0
             init() {
                Car.count += 1
             }
        }
        let c1 = car()
        let c2 = car()
        let c3 = car()
        print(Car.count) // 結(jié)果是 3
        
    • 總結(jié):類屬性細(xì)節(jié)

      • 不同于 存儲實(shí)例屬性,你必須給 存儲類型屬性 設(shè)定初始值隘马,因?yàn)轭愋蜎]有像實(shí)例那樣的init初始化器來初始化存儲屬性
      • 存儲類型屬性默認(rèn)就是lazy太防,會在第一次使用的時候才初始化,就算被多個線程同時訪問酸员,保證只會初始化一次
      • 存儲類型屬性可以是 let

      提示:枚舉類型也可以定義類型屬性(存儲類型屬性蜒车、計(jì)算類型屬性)

    • 類存儲屬性的使用-- 單利

      class Person {
         public static let share = Person() // 類存儲屬性,在這個程序中只有一份內(nèi)存
         private init() {}
      }
      

三沸呐、方法

  • 3.1醇王、類、枚舉崭添、結(jié)構(gòu)體 都可以定義 實(shí)例方法寓娩、類型方法

    • 實(shí)例方法(Instance Method):通過實(shí)例對象調(diào)用

    • 類型方法(Type Method):通過 類型調(diào)用,用 class/static關(guān)鍵字定義

      struct Car {
          static var count = 0
          init() {
              Car.count += 1
          }
          // 在函數(shù)(方法) 前面加上 class/static關(guān)鍵字 就可以變成類方法呼渣,用類名來調(diào)用
          static func getCount() -> Int { count }
      }
      let c1 = car()
      let c2 = car()
      let c3 = car()
      print(Car.getCount()) // 結(jié)果是 3
      

      提示:self

      • 在實(shí)例方法里面代表實(shí)例對象
      • 在類方法里面代表類型
        上代碼代碼 static func getCount() 里面的 count 等價于 self.count棘伴、Car.self.countCar.count
  • 3.2屁置、mutating 的使用

    • 結(jié)構(gòu)體和枚舉都是值類型焊夸,默認(rèn)情況下,值類型的屬性不能被自身的實(shí)例方法修改

    • 解決辦法:在 func 前面加上 mutaing 可以允許這種修改行為

      struct Point {
         var x = 0.0,y =  0.0
         mutating func moveBy(deltaX:Double,deltaY:Double)  {
             x += deltaX
             y += deltaY
             // 等效于上面的代碼
             //self = Point2(x: x + deltaX, y: y + deltaY)
         }
       }
      
      enum StateSwitch {
         case low,middle,high
         mutating func next() {
             switch self {
             case .low:
                  self = .middle
             case .middle:
                  self = .high
             case .high:
                  self = .low
             }
         }
      }
      
  • 3.3蓝角、@discardableResult 消除方法返回值沒使用的警告阱穗,如下

    struct Point {
         var x = 0.0,y =  0.0
         @discardableResult mutating func moveBy(deltaX:Double,deltaY:Double) -> Double  {
               x += deltaX
               y += deltaY
               return x + y
          }   
    }
    var point = Point()
    point.moveBy(deltaX: 2.0, deltaY: 2.0)
    

    提示:如果 函數(shù)moveBy不加 @discardableResult 饭冬,point.moveBy(deltaX: 2.0, deltaY: 2.0) 會提提示 Result of call to 'moveBy(deltaX:deltaY:)' is unused

四、下標(biāo)(subscrip)

  • 4.1揪阶、使用 subscrip 可以給任意類型(枚舉昌抠、結(jié)構(gòu)體、類)增加下標(biāo)功能鲁僚,有些地方翻譯為:下標(biāo)腳本

  • 4.2炊苫、subscrip的語法類似于實(shí)例方法、計(jì)算屬性冰沙,本質(zhì)就是方法 (函數(shù))

    struct Point {
        var x = 0.0,y = 0.0
        subscript(index: Int) -> Double {
      
             set {
                if index == 0 {
                    x = newValue
                } else if index == 1 {
                    y =  newValue
                }
             }
             get {
                if index ==  0 {
                   return x
                } else if index == 1 {
                   return y
                }
                return 0
             }
        }
    }
    
    var p = Point5()
    p[0] = 1.1
    p[1] = 2.2
    print(p.x)  // 1.1
    print(p.y)  //  2.2
    print(p[0]) // 1.1
    print(p[1]) // 2.2
    

    提示:

    • subscript 中定義的返回值類型決定了:get 方法的返回值 和 set 方法中 newValue 的類型
    • subscript 可以接受多個參數(shù)侨艾,并且類型任意
  • 4.3、subscript 下標(biāo)細(xì)節(jié)

    • 細(xì)節(jié)一:subscript 下標(biāo)可以沒有 set 方法拓挥,但必須有 get 方法唠梨,如果只有g(shù)et方法可以把 get 關(guān)鍵字去掉,如下

      struct Point {
         var x = 0.0,y = 0.0
         subscript(index: Int) -> Double {
                if index ==  0 {
                    return x
                } else if index == 1 {
                    return y
                }
                return 0
         }
      }
      
    • 細(xì)節(jié)二:可以設(shè)置參數(shù)標(biāo)簽

      struct Point {
          var x = 0.0,y = 0.0
          subscript(index i: Int) -> Double {
              if i == 0 {
                  return x
              } else if i == 1 {
                  return y
              }
              return 0
           }
      }
      var p = Point6()
      p.y = 22.0
      // 訪問的時候必須加上參數(shù)標(biāo)簽
      print(p[index: 1])
      
    • 細(xì)節(jié)三:下標(biāo)可以是 類型方法

      class Sum {
          static subscript(v1:Int,v2:Int) -> Int {
                return v1 + v2
          }
      }
      print(Sum[10,20])  // 打印結(jié)果是 30
      
  • 4.4撞叽、接收多個參數(shù)的下標(biāo)

    class Grid {
          var data = [
              [0, 1, 2],
              [3, 4, 5],
              [6, 7, 8]
           ]
          subscript(row: Int, column: Int) -> Int {
                set {
                    guard row >= 0 && row < 3 && column >= 0 && column < 3 else {
                       return
                    }
                    data[row][column] = newValue
                }
                get {
                    guard row >= 0 && row < 3 && column >= 0 && column < 3 else {
                       return 0 
                    }
                    return data[row][column]
                }
          } 
    }
    var grid = Grid()
    grid[0, 1] = 77  // 第1行第2列
    grid[1, 2] = 88  // 第2行第3列
    grid[2, 0] = 99  // 第3行第1列
    print(grid.data)
    

    打印結(jié)果如下:

    [[0, 77, 2],
    [3, 4, 88],
    [99, 7, 8]]
    
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末姻成,一起剝皮案震驚了整個濱河市插龄,隨后出現(xiàn)的幾起案子愿棋,更是在濱河造成了極大的恐慌,老刑警劉巖均牢,帶你破解...
    沈念sama閱讀 216,372評論 6 498
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件糠雨,死亡現(xiàn)場離奇詭異,居然都是意外死亡徘跪,警方通過查閱死者的電腦和手機(jī)甘邀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,368評論 3 392
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來垮庐,“玉大人松邪,你說我怎么就攤上這事∩诓椋” “怎么了逗抑?”我有些...
    開封第一講書人閱讀 162,415評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長寒亥。 經(jīng)常有香客問我邮府,道長,這世上最難降的妖魔是什么溉奕? 我笑而不...
    開封第一講書人閱讀 58,157評論 1 292
  • 正文 為了忘掉前任褂傀,我火速辦了婚禮,結(jié)果婚禮上加勤,老公的妹妹穿的比我還像新娘仙辟。我一直安慰自己同波,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,171評論 6 388
  • 文/花漫 我一把揭開白布叠国。 她就那樣靜靜地躺著参萄,像睡著了一般。 火紅的嫁衣襯著肌膚如雪煎饼。 梳的紋絲不亂的頭發(fā)上讹挎,一...
    開封第一講書人閱讀 51,125評論 1 297
  • 那天,我揣著相機(jī)與錄音吆玖,去河邊找鬼筒溃。 笑死,一個胖子當(dāng)著我的面吹牛沾乘,可吹牛的內(nèi)容都是我干的怜奖。 我是一名探鬼主播,決...
    沈念sama閱讀 40,028評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼翅阵,長吁一口氣:“原來是場噩夢啊……” “哼歪玲!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起掷匠,我...
    開封第一講書人閱讀 38,887評論 0 274
  • 序言:老撾萬榮一對情侶失蹤滥崩,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后讹语,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體钙皮,經(jīng)...
    沈念sama閱讀 45,310評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,533評論 2 332
  • 正文 我和宋清朗相戀三年顽决,在試婚紗的時候發(fā)現(xiàn)自己被綠了短条。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,690評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡才菠,死狀恐怖茸时,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情赋访,我是刑警寧澤可都,帶...
    沈念sama閱讀 35,411評論 5 343
  • 正文 年R本政府宣布,位于F島的核電站进每,受9級特大地震影響汹粤,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜田晚,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,004評論 3 325
  • 文/蒙蒙 一嘱兼、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧贤徒,春花似錦芹壕、人聲如沸汇四。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽通孽。三九已至,卻和暖如春睁壁,著一層夾襖步出監(jiān)牢的瞬間背苦,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,812評論 1 268
  • 我被黑心中介騙來泰國打工潘明, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留行剂,地道東北人。 一個月前我還...
    沈念sama閱讀 47,693評論 2 368
  • 正文 我出身青樓钳降,卻偏偏與公主長得像厚宰,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子遂填,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,577評論 2 353

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