属性と下付き
10908 ワード
ストレージのプロパティ
ストレージ属性は、定数属性(キーワードletで定義)と変数属性(キーワードvarで定義)に分けてデータを格納できます.ストレージ属性はクラスと構造体の2種類のSwiftオブジェクト向けタイプに適用されます.
ストレージ属性の概念
class Employee {
let no : Int = 0
var name : String = ""
var job : String?
var salary : Double = 0
var dept : Department?
}
struct Department {
let no : Int = 0
var name : String = ""
}
var emp = Employee()
emp.no = 100 //
let dept = Department()
dept.name = 30 //
let emp1 = Employee()
emp1.name = "Tony"
インスタンス通過点(.)演算子は属性を呼び出します.コードemp.No=100定数属性を変更すると、プログラムにコンパイルエラーが発生し、dept.name=30にもコンパイルエラーが発生します.インスタンスdept自体が定数であるため、その属性nameが変数属性であっても変更できません.しかしコードemp 1.name="Tony"はコンパイル可能であり,emp 1インスタンスも定数であり,nameは変数属性である.emp 1はクラスインスタンスであり、参照タイプであり、deptは構造体インスタンスであり、値タイプであるからである.参照タイプはポインタに相当し、定数は変更できますが、値タイプの定数は変更できません.
遅延ストレージ属性
print("-- --")
class Employee {
var no : Int = 0
var name : String = ""
var job : String?
var salary : Double = 0
lazy var dept : Department = Department()
}
struct Department {
let no : Int = 0
var name : String = ""
}
let emp = Employee()
deptプロパティの前にキーワードlazy宣言が追加され、deptプロパティが遅延ロードされます.遅延ロードは、名前の通りdeptプロパティが最初にアクセスしたときにのみロードされ、いつまでもアクセスしないと作成されず、メモリの消費量を削減できます.
属性オブザーバ
属性の変化を傍受するために、Swiftが提供する以下の属性観察者を使用することができる.
必要に応じて、一部またはすべての属性観察者を使用することができます.これらは、遅延ストレージ属性には適用できませんが、一般的なストレージ属性および計算属性に適用できます.
計算プロパティ
計算属性自体は、データを格納するのではなく、他の記憶属性から計算してデータを得る.ストレージ・データとは異なり、クラス、構造体、列挙で計算プロパティを定義できます.
計算プロパティコンセプト計算プロパティは、getter(値取得アクセサ)を使用して値を取得し、オプションのsetter(アクセスの設定)を使用して他のプロパティまたは変数の値を間接的に設定します.計算プロパティの構文形式は次のとおりです.
オブジェクトタイプ名向け{ストレージ属性...var計算属性名:属性データ型{get{return計算後属性値}set(新しい属性値){......}}
「オブジェクト向けタイプ」には、クラス、構造体、列挙の3種類があります.「ストレージ属性」は、多くのストレージ属性があることを示します.
例:
import UIKit
class Employee {
var no : Int = 0
var firstName : String = "Tony"
var lastName : String = "Guan"
var job : String?
var salary : Double = 0
lazy var dept : Department = Department()
var fullName : String {
get {
return firstName + "." + lastName
}
// set (newFullName) {
// var name = newFullName.componentsSeparatedByString()
// firstName = name[0]
// lastName = name[1]
// }
set {
var name = newValue.componentsSeparatedByString(".")
firstName = name[0]
lastName = name[1]
}
}
}
struct Department {
let no : Int = 0
var name : String = ""
}
var emp = Employee()
print(emp.fullName)
emp.fullName = "Tom.Guan"
print(emp.fullName)
UIKETフレームワークを導入し、set(newFullName)は以下の形式を省略し、Swiftのデフォルト名newValueを使用してnewFullNameを置き換えます.
set {
var name = newValue.componentsSeparatedByString(".")
firstName = name[0]
lastName = name[1]
}
newValue.componentsSeparatedByString(".")Stringの文字列分割方法componentsSeparatedByStringを使用して、点を文字列の分割記号として指定し、分割方法はString配列を返します.
読み取り専用計算プロパティ
計算プロパティはgetterアクセサのみで、setterアクセサがなく、読み取り専用計算プロパティです.計算プロパティを指定するには、setterアクセサを書く必要はありません.get{}コードも省略できます.修正例は、読み取り専用の計算プロパティです.コードは次のとおりです.
import UIKit
class Employee {
var no : Int = 0
var firstName : String = "Tony"
var lastName : String = "Guan"
var job : String?
var salary : Double = 0
lazy var dept : Department = Department()
var fullName : String {
return firstName + "." + lastName
}
}
struct Department {
let no : Int = 0
var name : String = ""
}
var emp = Employee()
print(emp.fullName)
読み取り専用の計算プロパティは割り当てられません.
構造体と列挙の計算プロパティ
サンプルコード:
import UIKit
struct Department {
let no : Int = 0
var name : String = "SALES"
var fullName : String {
return "Swift." + name + ".D"
}
}
var dept = Department()
print(dept.fullName)
enum WeekDays : String {
case Monday = "Mon."
case Tuesday = "Tue."
case Wednesday = "Wed."
case Thursday = "Thu."
case Friday = "Fri."
var message : String {
return "Today is " + self.rawValue
}
}
var day = WeekDays.Monday
print(day.message)
属性オブザーバ
属性の変化を傍受するために、Swiftは属性観察者を提供する.プロパティ・オブザーバは、変化前後の値が同じであっても、ストレージ・プロパティの変化をリスニングできます.ただし、遅延ストレージ属性と定数ストレージ属性の変化を傍受することはできません.
Swiftにおける属性観察者は主に以下の2つである.
プロパティ・オブザーバーの構文フォーマットは次のとおりです.
オブジェクトタイプ名{…varストレージ属性:属性データ型=初期化値{willSet(新しい値){…}didSet(旧値){......}}プロパティオブザーバの構文フォーマットは、計算プロパティよりも混乱します.「オブジェクト向けタイプ」には、ストレージ属性がサポートされていないため、列挙を含まないクラスと構造体が含まれます.
class Employee {
var no : Int = 0
var name : String = "Tony" {
willSet (newNameValue) {
print(" name :\(newNameValue)")
}
didSet (oldNameValue) {
print(" name :\(oldNameValue)")
}
}
var job : String?
var salary : Double = 0
var dept : Department?
}
struct Department {
var no : Int = 10 {
willSet {
print(" :\(newValue)")
}
didSet {
print(" :\(oldValue)")
}
}
var name : String = "RESEARCH"
}
var emp = Employee()
emp.no = 100
emp.name = "Smith"
var dept = Department()
dept.no = 30
静的プロパティ
クラスの設計:Account(銀行口座)クラスがあり、amount(口座金額)、interestRate(金利)、owner(口座名)の3つの属性があると仮定します.この3つのプロパティでは、amountとownerは人によって異なり、異なるアカウントではこれらの内容が異なり、すべてのアカウントのinterestRateは同じです.
amountおよびownerプロパティは、インスタンスプロパティと呼ばれるアカウント個体に関係します.interestRate属性は個体に関係なく、あるいはすべてのアカウント個体が共有しており、この属性は静的属性またはタイプ属性と呼ばれている.
3つのオブジェクト向けタイプ(構造体、列挙、クラス)は、それぞれ次のように構文形式で静的プロパティを定義できます.
struct構造体名{static var(またはlet)記憶属性="xxx"......static var計算属性名:属性データ型{get{return計算後属性値}set(新しい属性値){......}}
Enum列挙名{static var(またはlet)記憶属性="xxx"......static var計算属性名:属性データ型{get{return計算後属性値}set(新しい属性値){......}}
classクラス名{......class var計算属性名:属性データ型{get{return計算後属性値}set(新しい属性値){......}}構造体では、静的ストレージ属性と計算属性を定義できます.静的ストレージ属性を定義し、キーワードがstaticであることを宣言します.この属性は変数属性でも定数属性でも構いません.静的計算プロパティを定義し、使用するキーワードがstaticであることを宣言します.計算プロパティは定数ではありません.構造体の静的計算プロパティは、読み取り専用であってもよく、構文は次のとおりです.
static var計算属性名:属性データ型{return計算後属性値}定義列挙、列挙ではインスタンス記憶属性は定義できませんが、静的記憶属性を定義したり、静的計算属性を定義したりできます.列挙静的属性の定義は、構造体の静的属性を定義する構文と全く同じです.
インスタンスストレージ属性はクラスで定義できますが、静的ストレージ属性は定義できません.クラスでは、静的計算プロパティを定義できます.宣言に使用されるキーワードはclassであり、構造体や列挙の宣言とは異なります.
まとめ:
オブジェクト向けタイプ
インスタンスストレージのプロパティ
静的ストレージ属性
インスタンス計算プロパティ
静的計算プロパティ
クラス#クラス#
サポート
サポートされていません
サポート
サポート
こうぞうたい
サポート
サポート
サポート
サポート
列挙
サポートされていません
サポート
サポート
サポート
ヒント:静的計算プロパティでは、ストレージプロパティと計算プロパティを含むインスタンスプロパティにアクセスできませんが、他の静的プロパティにアクセスできます.インスタンス計算プロパティでは、インスタンスプロパティにも静的プロパティにもアクセスできます.
構造体の静的プロパティ
struct Account {
var amount : Double = 0.0 //
var owner : String = "" //
static var interestRate : Double = 0.668 //
static var staticProp : Double {
return interestRate * 1_000_000
}
var instanceProp : Double {
return Account.interestRate * amount
}
}
//
print(Account.staticProp)
var myAccount = Account()
//
myAccount.amount = 1_000_000
//
print(myAccount.instanceProp)
上記のコードはAccount構造体を定義し、static var interestRate:Double=0.668は静的記憶属性interestRateを定義し、コードstatic var staticProp:Double{return interestRate*1_000_000}は静的計算属性staticPropを定義し、その属性体ではinterestRateなどの静的属性にアクセスできる.コードvar instanceProp:Double{return Account.interestRate*amount}はインスタンス計算属性instancePropを定義し、その属性体で静的属性interestRateにアクセスでき、アクセス方式は「タイプ名.静的属性」である.インスタンス・プロパティへのアクセス方法は、「インスタンス・インスタンス・プロパティ」です.
静的プロパティの列挙
enum Account {
case
case
case
case
static var interestRate : Double = 0.668
static var staticProp : Double {
return interestRate * 1_000_000
}
var instanceProp : Double {
switch (self) {
case :
Account.interestRate = 0.667
case :
Account.interestRate = 0.669
case :
Account.interestRate = 0.666
case . :
Account.interestRate = 0.668
}
return Account.interestRate * 1_000_000
}
}
//
print(Account.staticProp)
var myAccount = Account.
//
print(myAccount.instanceProp)
クラス静的プロパティ
class Account {
var amount : Double = 0.0 //
var owner : String = "" //
var interestRate : Double = 0.668 //
class var staticProp : Double {
return 0.668 * 1_000_000
}
var instanceProp : Double {
return self.interestRate * self.amount
}
}
//
print(Account.staticProp)
var myAccount = Account()
//
myAccount.amount = 1_000_000
//
print(myAccount.instanceProp)
注意クラスでは静的ストレージプロパティを定義できません.コードclass var staticProp:Doubleは静的計算プロパティstaticPropを定義し、キーワードはclassです.selfは、現在のインスタンス自体を指します.
下付き文字の使用
配列や辞書にアクセスする場合は、下付きのアクセスを使用できます.配列の下付き文字は整数型インデックスで、辞書の下付き文字はその「キー」です.
下付き概念Swiftでは、いくつかの集合タイプを定義できます.これらの属性の要素は下付きでアクセスできます.Swiftの下付き文字は、Javaのインデックス属性とC#のインデックスに相当します.
下付きテキストでアクセスする構文の形式は次のとおりです.
オブジェクトタイプ名向け{その他の属性……subscript(パラメータ:パラメータデータ型)->戻り値データ型{get{return戻り値}set(新しい属性値){…}
「オブジェクト向けタイプ」には、クラス、構造体、列挙の3種類があります.下付きはsubscriptキーワード宣言を採用しています.下のアイコンには、計算プロパティに似たgetterおよびsetterアクセサもあります.
例:2 D配列はSwiftで2 D配列が提供されず、1 D配列Arrayのみが提供されます.2 D配列タイプをカスタマイズし、2つの下付きパラメータで要素にアクセスできます.形式的にはC言語の2 D配列に似ています.
下付きの2 D配列のサンプルコードは次のとおりです.
struct DoubleDimensionalArray {
let rows : Int, columns : Int
var grid : [Int]
init(rows: Int, columns: Int) {
self.rows = rows
self.columns = columns
grid = Array(count:rows * columns, repeatedValue:0)
}
subscript(row: Int, col: Int) -> Int {
get {
return grid[(row * columns) + col]
}
set (newValue1) {
grid[(row * columns) + col] = newValue1
}
}
}
let COL_NUM = 10
let ROW_NUM = 10
var ary2 = DoubleDimensionalArray(rows: ROW_NUM, columns: COL_NUM)
for i in 0 ..< ROW_NUM {
for j in 0 ..< COL_NUM {
ary2[i,j] = i * j
}
}
for i in 0 ..< ROW_NUM {
for j in 0 ..< COL_NUM {
print("\t \(ary2[i,j])")
}
print("
")
}