プロパティの(価)値
前回予告したとおり、
しかしそもそも
iOSの辞書によると
値の中の値
それではSwiftにおけるプロパティとはいったいなんでしょうか? 断言する前に実例を見てみましょう。Playgroundで次を入力してみてください。
"swift".description // "swift"
(42).description // "42"
(42.195).description // "42.195"
[42].description // "[42]"
["swift":4.1].description
// "["swift": 4.0999999999999996]"
それぞれの値を文字列にしたものが""に囲まれて表示されているはずです。これがそれぞれの値.descriptionという名のプロパティ
今度は.descriptionを.hashValueにしてみましょう。StringやIntやDoubleではこのようにIntの値が出てきますが……、
"swift".hashValue // 4799434080856491603 (42).hashValue // 42 (42.195).hashValue // 4631135235630652457
ArrayやDictionaryだとエラーになります
[42].hashValue // error: value of type '[Int]' has no member 'hashValue' ["swift":4.1].hashValue // error: value of type '[String : Double]' has no member 'hashValue'
どんな値がどんなプロパティを持つかは、
今そこにあるプロパティ・その場で作られるプロパティ
プロパティは型によって決まる。具体的にその様子を見てみましょう。
struct Point<T:FloatingPoint> {
var x:T
var y:T
}
PointというStructを作ったうえで使ってみます。
var dp = Point(x:3,y:4) dp.x // 3 dp.y // 4
.xと.yというプロパティが存在し、
このPointに原点.distanceというプロパティを付け加えてみましょう。
import Darwin // for sqrt()
extension Point {
var distance:T {
return sqrt(x*x + y*y)
}
}
実行結果は次のとおり。
dp.distance // 5
メモリにそのまま保持されているストアド・
「あれ? これってメソッド
extension Point {
func getDistance() -> T {
return sqrt(x*x + y*y)
}
}
dp.getDistance() // 5
ここで.getDistance()の()を取ってみましょう。エラーにはならず、() -> Doubleと出てくるはずです。
そうなのです。Swiftではメソッドもまた単なる関数型のストアド・()を付けずに実行されるメソッドにすぎないのです。
しかし、
.distanceの定義を次のように変えてみます。
extension Point {
var distance:T {
get {
return sqrt(x*x + y*y)
}
set {
let d = distance
x *= newValue / d
y *= newValue / d
}
}
}
すると……、
dp.distance = 10 dp.x // 6 dp.y // 8
これは、
extension Point {
func getDistance() -> T {
return sqrt(x*x + y*y)
}
mutating func setDistance(_ newValue:T) {
let d = self.getDistance()
x *= newValue / d
y *= newValue / d
}
}
ほかの言語でも、()の有無に過ぎず、
添字もsubscriptという名のプロパティ
配列
[42][0] // 0 ["swift":4.1]["swift"] // 4.1
しかしよく考えてみると、
例として、IntをBoolの配列として操作できるようにしてみます。
extension Int {
subscript(_ i:Int)->Bool {
get {
return self & (1 << i) == 0
}
set {
var mask = 1 << i
if !newValue {
mask = ~mask
self &= mask
} else {
self |= mask
}
}
}
}
実行してみます。
var v = 0; v[1] = true // v = 000010 == 2 v[3] = true // v = 001010 == 10 v[5] = true // v = 101010 == 42 v // 42
Swiftではsubscriptというメソッド=プロパティを定義することによって、
ちなみに と書くことはできません。エラーになるべきなのですが、 Rubyではクラス自体もオブジェクトですが、 こうしてみると、 1つは、 当然ながら、 もう1つは、 何でも入るかわりにそのままでは何もできません。何もできないように組込みプロパティが存在しないだけではなく、 そして最後に総称型 を と書き直すことはできません。別の言い方をすると、 値があるところにプロパティがあり、 (ほぼ) 次回もまた、 2022年8月18日発売subscriptというのはSwiftではキーワード扱いなので、[42].subscript(0)
% swift
Welcome to Apple Swift version 4.0.3 (swiftlang-900.0.74.1 clang-900.0.39.2). Type :help for assistance.
1> [42].subscript(0)
Segmentation fault
型もまた値。そして値には……
.selfというプロパティを使います。type(of:42) == Int.self // true
type(of:42.0) == Int.self // false何でもはできないわよ。できることだけ
Optional。var v:Int? = nil
v.hashValue // error: value of optional type
'Int?' not unwrapped;?か!でunwrapせねばならず、Optionalではありません。Optionalの存在意義を考えれば、Any。extension Any { // error: non-nominal type 'Any'
cannot be extended
}extensionすることも禁止されています。使うときにはasなどで中身を取り出すという意味で、Optionalと同様に自然です。func id<T>(_ x:T)->T {
return x
}let idd<T>:(T)->T = { return $0 }[42]の型はArrayではなくArray<Int>であり、["swift":4.の型はDictionaryではなくDictionary<String,Double>であることを考えれば、まとめ
AnyおよびOptional、.subscriptという名のメソッドは禁則事項本誌最新号をチェック!
Software Design 2022年9月号
B5判/
定価1,342円
MySQL アプリ開発者の必修5科目
不意なトラブルに困らないためのRDB基礎知識
OSSソースコードリーディングのススメ
企業のシステムを支えるOSとエコシステムの全貌
今さら聞けないSSH
MySQLで学ぶ文字コード
新生
