2008年、AppleはiPhone SDK2.0を発表してリリースしました。このイベントはソフトウェア開発に新たな革命をもたらし、新しい種類の開発者が誕生しました。彼らは今として認識されています iOS開発者 。
これらの開発者の多くはこれまでObjective-Cを使用したことがなく、それがAppleが彼らに投げかけた最初の課題でした。なじみのない構文と手動のメモリ管理にもかかわらず、それは大成功を収め、AppStoreに数万のアプリを投入するのに役立ちました。 Appleは、リリースごとにObjective-Cを継続的に改善し、ブロックとリテラルを追加し、自動参照カウントによるメモリ管理を簡素化し、最新のプログラミング言語を示す他の多くの機能を提供しました。
そして、Objective-Cの改善と作業を6年間行った後、Appleは開発者に別の課題を投げかけることにしました。繰り返しになりますが、iOS開発者は新しいプログラミング言語を学ぶ必要があります。 迅速 。 Swiftは、Objective-CとCの両方との相互作用を維持しながら、安全でないポインター管理を削除し、強力な新機能を導入します。
Swift 1.0はすでに安定した強力な開発プラットフォームであり、今後数年間で興味深い方法で進化することは間違いありません。それは明らかにiOS開発の未来であるため、この新しい言語の探索を開始する絶好の機会です。
このチュートリアルの目的は、 Objective-C開発者 新しいSwift言語機能の概要。次のステップに進み、日常業務でSwiftの採用を開始するのに役立ちます。私はObjective-Cの説明にあまり時間をかけず、iOS開発に精通していることを前提としています。
Swiftの探索を開始するには、必要なのは AppStoreからXCodeをダウンロードします 実験する遊び場を作ります。この記事で言及されているすべての例は、この方法で行われます。
AppleのSwiftホームページ Swiftプログラミングを学ぶための最良のリファレンスです。あなたはそれがかけがえのないものであることがわかるでしょう、そしてあなたがそうするまで Swift開発で完全にスピードアップ 頻繁にここに戻ってくると思います。
Swiftでの変数の宣言は、var
を使用して行われます。キーワード。
var x = 1 var s = 'Hello'
2つの変数x
に気付くでしょう。およびs
さまざまなタイプがあります。 x
は整数ですが、s
文字列です。 Swiftはタイプセーフな言語であり、割り当てられた値から変数タイプを推測します。コードを読みやすくしたい場合は、オプションで変数のタイプに注釈を付けることができます。
var y: Int y = 2
定数は似ていますが、let
を使用して宣言しますvar
の代わりに。定数の値はコンパイル時に知る必要はありませんが、値を1回だけ割り当てる必要があります。
let c1 = 1 // Constant known at compile time var v = arc4random() let c2 = v // Constant known only at run time
それらの名前が示すように、それらは不変であるため、次のコードはコンパイル時エラーを引き起こします。
let c = 1 c = 3 // error
他の型も定数として宣言できます。たとえば、次のコードは配列を定数として宣言しており、要素のいずれかを変更しようとすると、Swiftコンパイラはエラーを報告します。
var arr2 = [4, 5, 6] arr2[0] = 8 print (arr2) // [8, 5, 6] let arr = [1, 2, 3] a[0] = 5 // error
定数は宣言時に初期化する必要があり、変数は使用前に初期化する必要があります。では、Objective-Cはどこにありますかnil
同等ですか?スイフトが紹介する オプション値 。オプションの値は、値を持つことも、nil
にすることもできます。次のコードを見ると、x
に気付くでしょう。 Optional
が割り当てられました2014
の値。これは、Swiftコンパイラがx
を認識していたことを意味します。 nil
の場合もあります。
var s = '2014' var x = s.toInt() print(x) // Optional(2014)
このコードに変更を加えて値を割り当てる場合'abc'
整数に変換できないs
に、x
に気付くでしょう。現在はa nil
です。
var s = 'abc' var x = s.toInt() print(x) // nil
toInt()
の戻り値の型関数はInt?
です。これは オプションのInt 。 x
で標準関数を呼び出してみましょう。
var x = '2014'.toInt() print(x.successor()) // error
x
であるため、コンパイラはエラーを通知します。は オプションであり、潜在的にゼロになる可能性があります 。テストする必要がありますx
まず、successor
であることを確認してください関数は、nil
ではなく実数で呼び出されます値:
java、c、およびcppファイル拡張子は、一般的に次のどれに使用されますか?
var x = '2014'.toInt() if x != nil { print(x!.successor()) // 2015 }
開封する必要があることに注意してください x
感嘆符(!)を追加する 。 x
と確信できる場合値が含まれている場合、それにアクセスできます。そうしないと、ランタイムエラーが発生します。 Swiftが呼ぶこともできます オプションのバインディング 、オプションを非オプション変数に変換する
let x = '123'.toInt() if let y = x { print(y) }
if
のコードステートメントはx
の場合にのみ実行されますに値があり、それをy
に割り当てます。 y
をアンラップする必要はないことに注意してください。x
がわかっているため、タイプはオプションではありません。 nil
ではありません。
AppleのSwiftチュートリアルをチェックして、オプションや次のような優れた機能の詳細を確認してください。 オプションのチェーン
Objective-Cでは、文字列のフォーマットは通常stringWithFormat:
で行われます。方法:
NSString *user = @'Gabriel'; int days = 3; NSString *s = [NSString stringWithFormat:@'posted by %@ (%d days ago)', user, days];
Swiftには次の機能があります 文字列補間 同じことをしますが、よりコンパクトで読みやすくなります。
let user = 'Gabriel' let days = 3 let s = 'posted by (user) (days) ago'
次の式を使用することもできます。
let width = 2 let height = 3 let s = 'Area for square with sides (width) and (height) is (width*height)'
Swiftの文字列補間とその他の新機能の詳細については、 ここに 。
Swiftの関数定義はCとは異なります。サンプルの関数定義は以下のとおりです。
func someFunction(s:String, i: Int) -> Bool { ... // code }
Swift関数はファーストクラスのタイプです 。これは、関数を変数に割り当てたり、パラメーターとして他の関数に渡したり、戻り値の型にすることができることを意味します。
func stringLength(s:String) -> Int { return countElements(s) } func stringValue(s:String) -> Int { if let x = s.toInt() { return x } return 0 } func doSomething(f:String -> Int, s:String) -> Int { return f(s).successor() } let f1 = stringLength let f2 = stringValue doSomething(f1, '123') // 4 doSomething(f2, '123') // 124
繰り返しますが、Swiftはf1
のタイプを推測しますおよびf2
(String
-> Int
)、ただし、明示的に定義することもできます。
let f1:String -> Int = stringLength
関数は他の関数を返すこともできます。
func compareGreaterThan(a: Int, b: Int) -> Bool { return a > b } func compareLessThan(a: Int, b: Int) -> Bool { return a (Int, Int) -> Bool { if greaterThan { return compareGreaterThan } else { return compareLessThan } } let f = comparator(true) println(f(5, 9))
Swiftの機能のガイドがあります ここに 。
Swiftの列挙は、Objective-Cよりもはるかに強力です。 Swiftの構造体として、メソッドを持つことができ、値によって渡されます。
enum MobileDevice : String { case iPhone = 'iPhone', Android = 'Android', WP8 = 'Windows Phone8', BB = 'BlackBerry' func name() -> String { return self.toRaw() } } let m = MobileDevice.Android print(m.name()) // 'Android'
Objective-Cとは異なり、Swift列挙は、整数に加えて、文字列、文字、または浮動小数点数を各メンバーの値として割り当てることができます。便利なtoRaw()
メソッドは、各メンバーに割り当てられた値を返します。
列挙はパラメータ化することもできます:
enum Location { case Address(street:String, city:String) case LatLon(lat:Float, lon:Float) func description() -> String { switch self { case let .Address(street, city): return street + ', ' + city case let .LatLon(lat, lon): return '((lat), (lon))' } } } let loc1 = Location.Address(street: '2070 Fell St', city: 'San Francisco') let loc2 = Location.LatLon(lat: 23.117, lon: 45.899) print(loc1.description()) // '2070 Fell St, San Francisco' print(loc2.description()) // '(23.117, 45.988)'
列挙に関する詳細情報が利用可能です ここに 。
タプルは、複数の値を1つの複合値にグループ化します。タプル内の値は任意のタイプにすることができ、互いに同じタイプである必要はありません。
let person = ('Gabriel', 'Kirkpatrick') print(person.0) // Gabriel
個々のタプル要素に名前を付けることもできます。
let person = (first: 'Gabriel', last: 'Kirkpatrick') print(person.first)
タプルは、複数の値を返す必要がある関数の戻り値の型として非常に便利です。
SQLServerのパフォーマンスチューニングのヒント
func intDivision(a: Int, b: Int) -> (quotient: Int, remainder: Int) { return (a/b, a%b) } print(intDivision(11, 3)) // (3, 2) let result = intDivision(15, 4) print(result.remainder) // 3
Objective-Cとは異なり、Swiftはswitchステートメントでパターンマッチングをサポートしています。
let complex = (2.0, 1.1) // real and imaginary parts switch complex { case (0, 0): println('Number is zero') case (_, 0): println('Number is real') default: println('Number is imaginary') }
2番目のケースでは、数値の実数部分を気にしないため、_
を使用します。何にでもマッチします。いずれの場合も、追加の条件を確認することもできます。そのためには、パターン値を定数にバインドする必要があります。
let complex = (2.0, 1.1) switch complex { case (0, 0): println('Number is zero') case (let a, 0) where a > 0: println('Number is real and positive') case (let a, 0) where a <0: println('Number is real and negative') case (0, let b) where b != 0: println('Number has only imaginary part') case let (a, b): println('Number is imaginary with distance (a*a + b*b)') }
比較またはcaseステートメントで使用する値のみをバインドする必要があることに注意してください。
タプルの詳細については、 ここに 。
Objective-Cとは異なり、Swiftでは、カスタムクラスと構造用に個別のインターフェイスファイルと実装ファイルを作成する必要はありません。 Swiftを学習すると、単一のファイルでクラスまたは構造を定義する方法を学習し、そのクラスまたは構造への外部インターフェイスが他のコードで自動的に使用できるようになります。
クラス定義は非常に単純です。
class Bottle { var volume: Int = 1000 func description() -> String { return 'This bottle has (volume) ml' } } let b = Bottle() print(b.description())
ご覧のように、 宣言と実装は同じファイルにあります 。 Swiftはヘッダーファイルと実装ファイルを使用しなくなりました。この例にラベルを追加しましょう。
class Bottle { var volume: Int = 1000 var label:String func description() -> String { return 'This bottle of (label) has (volume) ml' } }
labelはオプションではない変数であり、Bottleがインスタンス化されたときに値を保持しないため、コンパイラは文句を言います。初期化子を追加する必要があります。
class Bottle { var volume: Int = 1000 var label:String init(label:String) { self.label = label } func description() -> String { return 'This bottle of (label) has (volume) ml' } }
または、Optional
を使用できます初期化されないプロパティのタイプ。次の例では、volume
を作成しましたOptional Integer
:
class Bottle { var volume: Int? var label:String init(label:String) { self.label = label } func description() -> String { if self.volume != nil { return 'This bottle of (label) has (volume!) ml' } else { return 'A bootle of (label)' } } }
Swift言語にもstructs
がありますが、Objective-Cよりもはるかに柔軟性があります。次のコードチュートリアルでは、struct
を定義しています。
struct Seat { var row: Int var letter:String init (row: Int, letter:String) { self.row = row self.letter = letter } func description() -> String { return '(row)-(letter)' } }
Swiftのクラスと同様に、構造体はメソッド、プロパティ、初期化子を持ち、プロトコルに準拠することができます。クラスと構造の主な違いは、 クラスは参照によって渡され、構造体は値によって渡されます 。
この例は、参照によるクラスの受け渡しを示しています。
let b = Bottle() print(b.description()) // 'b' bottle has 1000 ml var b2 = b b.volume = 750 print(b2.description()) // 'b' and 'b2' bottles have 750 ml
struct
で同様のケースを試してみると、変数が値で渡されていることがわかります。
var s1 = Seat(row: 14, letter:'A') var s2 = s1 s1.letter = 'B' print(s1.description()) // 14-B print(s2.description()) // 14-A
いつstruct
を使用すべきかいつclass
を使用する必要がありますか? Objective-CおよびCと同様に、いくつかの値をグループ化する必要がある場合は構造体を使用し、それらが参照されるのではなくコピーされることを期待します。たとえば、複素数、2Dまたは3Dポイント、またはRGBカラー。
クラスのインスタンスは、伝統的にオブジェクトとして知られています。ただし、Swiftのクラスと構造は他の言語よりも機能がはるかに近く、多くの機能はクラスまたは構造タイプのインスタンスに適用できます。このため、Swiftリファレンスで使用されるより一般的な用語はinstance
であり、これら2つのいずれにも適用されます。
Swiftのクラスと構造の基本を学ぶ ここに 。
前に見たように、Swiftのプロパティはvar
で宣言されていますクラスまたは構造体定義内のキーワード。 let
で定数を宣言することもできますステートメント。
struct FixedPointNumber { var digits: Int let decimals: Int } var n = FixedPointNumber(digits: 12345, decimals: 2) n.digits = 4567 // ok n.decimals = 3 // error, decimals is a constant
また、接頭辞weak
を付けない限り、クラスプロパティは強く参照されることに注意してください。キーワード。ただし、オプションではないプロパティが弱い微妙な点もあるので、 自動参照カウントの章 AppleのSwiftガイドにあります。
計算されたプロパティは実際には値を格納しません。代わりに、他のプロパティと値を間接的に取得および設定するためのゲッターとオプションのセッターを提供します。
次のコードは、計算値sign
のサンプルを提供します。
enum Sign { case Positive case Negative } struct SomeNumber { var number:Int var sign:Sign { get { if number <0 { return Sign.Negative } else { return Sign.Positive } } set (newSign) { if (newSign == Sign.Negative) { self.number = -abs(self.number) } else { self.number = abs(self.number) } } } }
ゲッターを実装するだけで、読み取り専用プロパティを定義することもできます。
struct SomeNumber { var number:Int var isEven:Bool { get { return number % 2 == 0 } } }
Objective-Cでは、プロパティは通常、コンパイラによって明示的または自動的に作成されたインスタンス変数によってサポートされます。一方、Swiftでは、 プロパティに対応するインスタンス変数がありません 。つまり、プロパティのバッキングストアに直接アクセスすることはできません。これがObjective-Cにあるとしましょう
// .h @interface OnlyInitialString : NSObject @property(strong) NSString *string; @end // .m @implementation OnlyInitialString - (void)setString:(NSString *newString) { if (newString.length > 0) { _string = [newString substringToIndex:1]; } else { _string = @''; } } @end
Swiftでは、計算されたプロパティにはバッキングストアがないため、次のようなことを行う必要があります。
class OnlyInitialString { var initial:String = '' var string:String { set (newString) { if countElements(newString) > 0 { self.initial = newString.substringToIndex(advance(newString.startIndex, 1)) } else { self.initial = '' } } get { return self.initial } } }
プロパティについて詳しく説明します ここに
ジェネリックス、Objective-Cライブラリとの相互作用、クロージャ、オプションのチェーン、演算子のオーバーロードなど、Swiftで学ぶべき重要な新しいことがたくさんあります。単一のチュートリアルで新しい言語を完全に説明することはできませんが、Swiftプログラミングの学習についてさらに多くのことが書かれることは間違いありません。しかし、私はこれを信じています クイックリード 時間を見つけてSwift言語の詳細を学ぶことができなかった多くの、Objective-C開発者が軌道に乗り、Swiftの鳥に彼らを新たな高みへと導く手助けをします。