swift類與結(jié)構(gòu)

類與結(jié)構(gòu)

swift的結(jié)構(gòu)體增添了很多類的功能: 定義函數(shù),定義下標(biāo),有構(gòu)造函數(shù),可以擴(kuò)展,還可以遵循協(xié)議來(lái)提供某種標(biāo)準(zhǔn)化的功能。
并且結(jié)構(gòu)有一個(gè)默認(rèn)的逐一構(gòu)造函數(shù)(每個(gè)屬性都有的初始化函數(shù)).

結(jié)構(gòu)和枚舉是值類型 類是引用類型

在Swift中,很多基本數(shù)據(jù)類型,例如String、Array和Dictionary都是用結(jié)構(gòu)實(shí)現(xiàn)的。也就意味著他們被賦值給一個(gè)常量或者變量、或者被傳入一個(gè)方法時(shí)是通過(guò)復(fù)制的方式實(shí)現(xiàn)的。

一,屬性

swift有兩種屬性。1 存儲(chǔ)屬性 2 計(jì)算屬性
存儲(chǔ)屬性就是平時(shí)我們理解的屬性,這個(gè)計(jì)算屬性意思是可以通過(guò)存儲(chǔ)屬性計(jì)算出來(lái)的。上代碼一看便知:

struct Point {
    var x = 0.0, y = 0.0
}
struct Size {
    var width = 0.0, height = 0.0
}
struct Rect {
    var origin = Point()
    var size = Size()
//這個(gè)center是通過(guò)已知屬性計(jì)算出來(lái)的(計(jì)算屬性只能聲明成var)
    var center: Point {
        get {
            let centerX = origin.x + (size.width / 2)
            let centerY = origin.y + (size.height / 2)
            return Point(x: centerX, y: centerY)
        }
        set(newCenter) {
            //這里不能在調(diào)用setcenter ,會(huì)導(dǎo)致死循環(huán)
            origin.x = newCenter.x - (size.width / 2)
            origin.y = newCenter.y - (size.height / 2)
        }
    }
}

在上面代碼中origin和size是存儲(chǔ)屬性,center是計(jì)算屬性.他里面這個(gè)set方法是可以改變相關(guān)存儲(chǔ)屬性值得。當(dāng)沒(méi)有set方法的時(shí)候叫做 “只讀計(jì)算屬性”,這時(shí)候可以吧get{ }省略,只留get里面的東西就可以了如下。

struct Rect {
    var origin = Point();
    var size   = Size();
    var center:Point{
        let centerX = origin.x + (size.width / 2);
        let centerY = origin.y + (size.height / 2);
        return Point(x: centerX, y: centerY);
    }
}

懶惰屬性

當(dāng)屬性第一次被使用的時(shí)候才被初始化,就是oc中經(jīng)常用哪個(gè)懶加載.只不過(guò)不用我們?cè)趃etter方法里面自己判斷為空的時(shí)候再初始化,聲明的時(shí)候前面加一個(gè)lazy就哦了

lazy var obj = SomeClass();

屬性觀察者

可以為每個(gè)屬性添加一個(gè)willSet,didSet來(lái)監(jiān)聽屬性值的變化.這個(gè)比較方便,不用像oc那樣添加觀察者.

    var age : Int {
        willSet{
        //此時(shí)age還沒(méi)有改變,swift添加了默認(rèn)參數(shù)newValue表示新值
       //這里如果再調(diào)用 set age 不會(huì)造成死循環(huán)
      // age = 10
        }
        
        didSet{
        //此時(shí)age已經(jīng)改變,同樣swift自動(dòng)添加了參數(shù)oldValue表示之前的值
        }
    }

如果一個(gè)帶有觀察者的屬性被被當(dāng)做in-out參數(shù)使用的時(shí),會(huì)引起觀察者被調(diào)用.

類屬性

類屬性和其他語(yǔ)言一樣是屬于類的屬性,可直接通過(guò)類名使用,swift中結(jié)構(gòu),枚舉,類都可以定義類屬性.語(yǔ)法是在前面加一個(gè)static關(guān)鍵字, 可以是var 和 let

在為類定義計(jì)算型類型屬性時(shí),可以改用關(guān)鍵字class 來(lái)支持子類對(duì)父
類的實(shí)現(xiàn)進(jìn)行重

struct SomeStructure {
    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {
        return 1
    }
}

enum SomeEnumeration {
    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {
        return 6
    }
}

class SomeClass {
    static var storedTypeProperty = "Some value."
    static var computedTypeProperty: Int {
        return 27
    }
  //這里用了class來(lái)聲明類屬性,因?yàn)閛verrideableComputedTypeProperty是個(gè)計(jì)算屬性,并且希望子類可以重寫這個(gè)計(jì)算實(shí)現(xiàn)
    class var overrideableComputedTypeProperty: Int {
        return 107
    }

}

通過(guò)閉包設(shè)置默認(rèn)屬性

注意閉包結(jié)尾的大括號(hào)后面接了一對(duì)空的小括號(hào)。這用來(lái)告訴 Swift 立即執(zhí)行此閉包。如果你忽略了這對(duì)括
號(hào),相當(dāng)于將閉包本身作為值賦值給了屬性,而不是將閉包的返回值賦值給屬性。

還有閉包中不能使用實(shí)例的其他屬性,因?yàn)榇藭r(shí)實(shí)例還沒(méi)有初始化文成,也不能用self。

class SomeClass {
  let someProperty: SomeType = {
    // 在這個(gè)閉包中給 someProperty 創(chuàng)建一個(gè)默認(rèn)值
    // someValue 必須和 SomeType 類型相同
    return someValue
  }()
}

二, 方法

swift的類,結(jié)構(gòu)和枚舉都可以定義實(shí)例方法和類方法,是的沒(méi)錯(cuò) 枚舉也可以定義方法.

特點(diǎn)

1, 結(jié)構(gòu)和枚舉都是值類型。默認(rèn)情況下,值類型的屬性在自己的實(shí)例方法內(nèi)部是不能修改的。就是說(shuō)枚舉和結(jié)構(gòu)中的方法在默認(rèn)情況下不能修改自身的屬性。如果想修改,要在方法前面添加mutating 關(guān)鍵字.
2, swift函數(shù)的參數(shù)有兩個(gè)標(biāo)簽
外部標(biāo)簽是為了提高代碼的可讀性,swift和oc一樣努力讓方法調(diào)用看起來(lái)想一個(gè)句子般易讀。

func someFunc(外部調(diào)用參數(shù)  函數(shù)局部變量名:Int){ 函數(shù)內(nèi)容}

 func someFunc(outParam  inParam:Int){  }
//調(diào)用時(shí)候是這樣的
someFunc(outParam: 5);
//這個(gè)outParam可以不加 那么默認(rèn)用inParam
func someFunc( inParam:Int){  }
someFunc(inParam: 5)

//如果一個(gè)都不想用的話,函數(shù)這樣聲明
func someFunc(_ inParam:Int){}
someFunc(5)

*在方法內(nèi)部甚至可以給self重新賦值
struct Point {
    var x = 0.0, y = 0.0
    mutating func moveBy(x deltaX: Double, y deltaY: Double) {
        x += deltaX
        y += deltaY
    }
}
var somePoint = Point(x: 1.0, y: 1.0)
somePoint.moveBy(x: 2.0, y: 3.0)
print("The point is now at (\(somePoint.x), \(somePoint.y))")

//在方法內(nèi)部甚至可以給self重新賦值
enum TriStateSwitch {
    case off, low, high
    mutating func next() {
        switch self {
        case .off:
            self = .low
        case .low:
            self = .high
        case .high:
            self = .off
        }
    }
}
var ovenLight = TriStateSwitch.low
ovenLight.next()
同樣可以使用static來(lái)定義類方法,class類型可以使用class關(guān)鍵字,以允許子類重寫父類的實(shí)現(xiàn)。注意swift的子類可以 重寫父類的類方法。

三, 下標(biāo)

下標(biāo)語(yǔ)法是提供了一種方式讓我們可以通過(guò)中括號(hào)的方式( someObj[] )去調(diào)用一段代碼,有些時(shí)候更加方便的表示一種數(shù)據(jù)結(jié)構(gòu)。
類,枚舉,結(jié)構(gòu) 都可以使用下標(biāo)語(yǔ)法。

   struct Matrix {
    let rows: Int, columns: Int
    var grid: [Double]

    init(rows: Int, columns: Int) {
        self.rows = rows
        self.columns = columns
        grid = Array(repeat: 0.0, count: rows * columns)
    }

    func indexIsValid(row: Int, column: Int) -> Bool {
        return row >= 0 && row < rows && column >= 0 && column < columns
    }

    subscript(row: Int, column: Int) -> Double {
        get {
            assert(indexIsValid(row: row, column: column), "Index out of range")
            return grid[(row * columns) + column]
        }
        set {
            assert(indexIsValid(row: row, column: column), "Index out of range")
            grid[(row * columns) + column] = newValue
        }
    }
}

//創(chuàng)建一個(gè)矩陣
var matrix = Matrix(rows: 2, columns: 2)
//使用下標(biāo)語(yǔ)法設(shè)置矩陣的值(在表示矩陣這種數(shù)據(jù)結(jié)構(gòu)的時(shí)候下標(biāo)語(yǔ)法會(huì)更加清晰易讀)
matrix[0, 1] = 1.5
matrix[1, 0] = 3.2

下標(biāo)語(yǔ)法是這樣的:通過(guò) subscript 關(guān)鍵字
這個(gè)看起來(lái)和計(jì)算屬性有點(diǎn)像。只不過(guò)他不是屬性,倒是可以看做一種方法.

subscript(param)->resultType{
  get{

      }
 set{
//set時(shí)候會(huì)有個(gè)默認(rèn)參數(shù)newValue  就是即將set的值
     }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容