Upload
tomohiro-kumagai
View
5.197
Download
0
Embed Size (px)
Citation preview
// 定義は、外部引数名、内部変数名、型名を活用して紡ぐ func insert(_ newItem: Item, into position: Int)
// 使用時は、変数名も活用して紡ぐ bookshelf.insert(newBook, into: freeSpace)
// item が冗長だったり、freeSpace が説明不足だったり bookshelf.insert(item: newBook, position: freeSpace)
// 定義を見れば、意図を汲めるけれど… func add(handler: () -> Void, for eventName: String)
// 使用時に、説明不足で主体から用途が想像しにくい document.add(handler: () -> Void, for: String)
// 定義時に名前で補足すると… func addEventHandler(_ handler: () -> Void, forEventName name: String)
// 使用時に用途を汲みやすくなる document.addEventHandler(handler: () -> Void,
forEventName: String)
// 動詞系で、自身を書き換えないなら、末尾に“ed”とか nonmutating func advanced(by n: Int) -> Int
// 動詞系で、自身を書き換えないなら、末尾に“ing”とか nonmutating func adding(_ other: Int) -> Int
// 動詞系で、自身を書き換えるなら、動詞そのもの mutating func add(_ other: Int)
// 名詞系で、自身を書き換えないなら、名詞そのもの nonmutating func squareRoot() -> Double
// 名詞系で、自身を書き換えるなら、先頭に“form”付与 mutating func formSquareRoot()
// 引数を書き換える場合も Mutating と同じく“form”付与 nonmutating func formIndex(after i: inout Int)
// 素直に命名するとラベルがアンバランスになる func cell(atColumn: Int, row: Int) -> Cell
// at をメソッド名に含めることでラベルが整う func cellAt(column: Int, row: Int) -> Cell
// タプルで表現することでもバランスが取れる func cell(at location: (column:Int, row:Int)) -> Cell
// bytes と count をとって初期化する init(bytes: UnsafeRawPointer, count: Int)
// value と radix と uppercase をとって初期化する init(_ value: Int, radix: Int, uppercase: Bool)
// lower と upper をとって初期化する init(lower: Bound, upper: Bound)
// Int 型の値を String 型で忠実に再現(全幅変換) struct String { init(_ value: Int, radix: Int = 10) }
// UInt32 型の値をビットパターンとして Int32 型に再解釈 struct Int32 { init(truncatingBitPattern pattern: UInt64) }
// Int 型の値を String 型にキャスト(全幅変換) let string = String(number, radix: 16)
// ビットパターンを指定して Int32 型を生成(Narrow 変換) let value = Int32(truncatingBitPattern: number)
// 範囲を生成 let range = MyRange(lower: start, upper: last)
// 自作の型なら、直接でも拡張でも自由に備えられる struct Bookshelf : Collection {
mutating func arrange() { … } }
// 他者が作ったものにも、拡張で備えられる extension Collection where Iterator.Element == Book {
func sortedByTitle() -> [Book] { … } }
// 全ての値が対等で、主体が定まらない func average(of values: Double...) -> Double
// 具体的な主体が定義に現れないため、所属できない func convert<T: Any, U: Compatible>(from: T) -> U
// プログラミングの分野では、絶対値は関数 abs で取得する func abs(_ x: Double) -> Double
struct Int128 {
fileprivate var low: UInt64 fileprivate var high: UInt64
// Int 型の値を Int128 型に全幅変換 init(_ value: Int) {
low = UInt64(value) high = 0 } }
extension Int {
// Int128 型の値を Int 型に全幅変換 init(_ value: Int128) {
guard value.high == 0 else { fatalError("Overflow") }
self = Int(value.low) } }
// お馴染みの Double から Int へのキャスト例 let taxIncluded = Int(Double(price) * (1 + tax))
// お馴染みのキャストと同じ書き方になる let endOfInteger = Int128(Int64.max) + 1
// 自作の Int128 から Int への変換もいつも通り let stride = Int(Int128.max / samples)
// 標準ライブラリーに規定されている性質
/// A type that can be compared for value equality. protocol Equatable {
/// Returns a Boolean value indicating /// whether two values are equal. static func ==(lhs: Self, rhs: Self) -> Bool }
// プロトコルで比較可能性を説明すると… extension Int128 : Equatable {
static func == (lhs: Int128, rhs: Int128) -> Bool {
return (lhs.low, lhs.high) == (rhs.low, rhs.high) } }
// 比較演算を使って比較可能になる Int128(1000) == Int128(1000) Int128(1000) != Int128(1000)
// 比較可能な要素を扱う場合だけ使えるようになっている extension Array where Element : Equatable {
func index(of element: Element) -> Int? }
// 配列で、要素からインデックスを特定できるようになる let values = [Int128(1), Int128(5), Int128(10)]
let index = values.index(of: Int128(5))
// 標準ライブラリーに規定されている性質
/// A type with a customized textual representation. protocol CustomStringConvertible {
/// A textual representation of this instance. var description: String { get } }
enum Device : CustomStringConvertible {
case iPhone, iPad, appleWatch
var description: String {
switch self { case .iPhone: return "iPhone" case .iPad: return "iPad" case .appleWatch: return " Watch" } }
let device = Device.appleWatch
// テキスト表現への Narrow 変換 let displayText = String(describing: device)
// テキスト表現に変換して、テキストコンソールに出力 print(device)
// String 型の文字列補完構文は、テキスト表現を使用 let message = "I love \(device)"
// 変数 floatValues が Array<Float> で定義されている let floatValues: [Float]
// サブスクリプトに範囲を渡すと、部分配列が取れる let slice = floatValues[2 ..< 6]
// 部分配列の型は ArraySlice<Float> になる type(of: slice) == ArraySlice<Float>.self
// 一般的な定義の仕方 func sum(of values: [Double]) -> Double {
return values.reduce(0, +) }
// Float 型の配列の部分配列の合計を計算 sum(of: floatValues[2 ..< 6].map(Double.init))
// 任意の浮動小数点数を対象にする func sum<T: FloatingPoint>(of values: [T]) -> T {
return values.reduce(0, +) }
// Float 型の配列の部分配列の合計を計算 sum(of: Array(floatValues[2 ..< 6]))
// 標準ライブラリーに規定されている性質
/// A type that provides sequential, /// iterated access to its elements. public protocol Sequence {
/// A type that provides the sequence's iteration /// interface and encapsulates its iteration state. associatedtype Iterator : IteratorProtocol
// 連続する任意の浮動小数点数を対象にする func sum<S: Sequence, T: FloatingPoint> (of values: S) -> T where S.Iterator.Element == T {
return values.reduce(0, +) }
// 連続する浮動小数点数の部分配列の合計を計算 sum(of: floatValues[2 ..< 6])
// 自身の値でストライドできる値を対象にする func sum<S: Sequence, T:Strideable>(of values: S) -> T where S.Iterator.Element == T, T.Stride == T {
return values.reduce(0) { $0.advanced(by: $1) } }
// 連続する値の部分配列の合計を計算 sum(of: floatValues[2 ..< 6]) sum(of: integerValues[2 ..< 6])
// 整数を対象とした合計関数 func sum<S:Sequence, T:Integer>(of values:S) -> T where S.Iterator.Element == T { return values.reduce(0, +) }
// 浮動小数点数を対象とした合計関数 func sum<S:Sequence, T:FloatingPoint>(of values:S) -> T where S.Iterator.Element == T { return values.reduce(0, +) }