※諸事情によりはてブロから転載
作成日
2014/06/03
更新日
2014/09/14
#Swift
##1 どんな言語?
- 読みはスイフト
- Objective-CとC言語の中間に位置する言語
- Apple曰くObjective-C Without Cとのことです
- LLVMコンパイラベース
- モダンかつObjective-Cよりも高速
- ソートでの処理速度でpython 1xとして、objective-c 2.8x , swift 3.9x
- Xcode記述時にリアルタイムに実行内容を確認できる
- 拡張子は「.swift」
##2 文法
セミコロンが要りません
コメントは以下のように従来通り
###1行コメント
// 1行コメント
###複数行コメント
/*
* 複数行コメント
*/
###タプル
複数の値を扱う概念です、Pythonなどでも使われています。
(Int, String)
とするとIntとStringを扱うタプルとみなされます。
この概念を使い返り値をタプルとすることで、複数の
返り値をまとめて返すことが可能になります。
整数範囲指定
「...」と「..<」を使うことで整数を範囲指定することができます
違いとしては範囲の上限を含むか、含まないかになります
- 「...」:上限を含む
- 「..<」 :上限を含めない
let a = 0
let b = 5
let c = a...b //-> [0, 1, 2, 3, 4, 5]
let d = a..<b //-> [0, 1, 2, 3, 4]
let e = 0...6 //-> [0, 1, 2, 3, 4, 5, 6]
Integers
####整数値の最大値、最小値を返す
やはりObjective-Cとは違い、Int型から処理を実行しています。
既にここから Objective-C without C が表現できているのでは
ないでしょうか。
var minValue = UInt8.min // UInt8の最小値である0を返します
var maxValue = UInt8.max // UInt8の最大値である255を返します
####Int/UInt
32-bit プラットフォームの Int32/UInt32と同義
64-bit プラットフォームの Int64/UInt64と同義
####Float
32-bit 浮動小数点値
####Double
64-bit 浮動小数点値
変数宣言
####型無し
代入される値から型を推論します
var apple = 10
var cocoa = "cocoa"
####型付き
もちろん型を付けて宣言もできます。
ここまで見るとJavaScript/TypeScriptっぽいですね
var apple : Int = 10
var cocoa : String = "cocoa"
####定数
変数に値を束縛します
Scalaにも同じ概念があるようです
let apple : Int = 10
let cocoa : String = "cocoa"
####好きな文字が(Unicodeの対応範囲で)変数/定数として宣言できます
let π = 3.14159
let 你好 = "你好世界"
文字列
####リテラル
"Hello world"
####比較
var str = "apple"
if str == "apple" {
// "apple" と等しい
}else{
// それ以外の文字列
}
####大文字変換
var normal = "Swift"
// UpperCase
var upper = normal.uppercaseString //-> SWIFT
####小文字変換
var normal = "Swift"
// LowerCase
var lower = normal.lowercaseString //-> swift
####数値変換
var a = "123"
var aNum : Int = a.toInt()!
####空文字チェック
var str = ""
if str.isEmpty {
// 文字列が空です
}else{
// 文字列は入ってます
}
if文
####通常
POP = 90 // 降水確率
if 0 <= POP || POP < 30 {
println("傘は必要ありません。")
} else if 30 <= POP || POP <= 100 {
println("傘を持っていく必要があります。")
} else {
println("対応していない値です")
}
####ifスコープ内のみの変数/定数宣言
if let accountID = searchAccountID("会員番号") {
// アカウントIDを取得、何らかの処理を実施
sendClient(accountID)
} else {
// アカウントIDが取れなかった場合
}
switch文
####通常
var someVar = 30
var result = ""
switch someVar{
case 10:
result += "ten"
case 20:
result += "twenty"
case 30:
result += "thirty"
default:
result += "unknown"
}
println(result)
//-> thirty
####範囲指定
let count = 3_000_000_000_000
let countedThings = "stars in the Milky Way"
var naturalCount: String
switch count {
case 0:
naturalCount = "no"
case 1...3:
naturalCount = "a few"
case 4...9:
naturalCount = "several"
case 10...99:
naturalCount = "tens of"
case 100...999:
naturalCount = "hundreds of"
case 1000...999_999:
naturalCount = "thousands of"
default:
naturalCount = "millions and millions of"
}
println("There are \(naturalCount) \(countedThings).")
//-> There are millions and millions of stars in the Milky Way.
####パターンマッチ
var point : (Int, Int) = (2, 2)
switch point {
case ("0", "0"):
println("(0, 0) is at the origin.")
case ("-2...2", "-2...2"):
println("(\(point.0), \(point.1)) is near the origin.")
default:
println("The point is at (\(point.0), \(point.1)).")
}
for文
####通常
for var index = 0; index < 3; ++index {
println("index is \(index)")
}
// index is 0
// index is 1
// index is 2
####範囲指定
for index in 1...5 {
println("\(index) times 5 is \(index * 5)")
}
####高速列挙
let names = ["Anna", "Alex", "Brian", "Jack"]
for name in names {
println("Hello, \(name)!")
}
// Hello, Anna!
// Hello, Alex!
// Hello, Brian!
// Hello, Jack!
####index省略
Swiftでは処理中のインデックスを気にする必要がないような処理では
_ を使うことにより省略して書くことができます。
for _ in 1...3 {
// 何らかの処理を3回実施します
}
メソッド
####定義
func sayHello(personName : String) -> String{
var greeting = "Hello, " + personName + "!"
return greeting
}
####呼び出し
println(sayHello("Anna"))
// prints "Hello, Anna!"
println(sayHello("Brian"))
// prints "Hello, Brian!"
####名前付き引数呼び出し
ruby2.0で導入されたものと非常に似ています
sayHello(personName:"Annna")
sayHello(personName:"Brian")
####可変長引数
// Double値の平均を求める
func arithmeticMean(numbers: Double...) -> Double {
var total: Double = 0
for number in numbers {
total += number
}
return total / Double(numbers.count)
}
arithmeticMean(1, 2, 3, 4, 5)
// 3.0 のDouble値が返ります
arithmeticMean(3, 8, 19)
// 10.0 のDouble値が返ります
####Generic定義
func swapTwoValues<T>(inout a: T, inout b: T) {
let temporaryA = a
a = b
b = temporaryA
}
####Genericメソッド呼び出し
var someInt = 3
var anotherInt = 107
swapTwoValues(&someInt, &anotherInt)
// 変数someIntは「107」, anotherIntは「3」
var someString = "hello"
var anotherString = "world"
swapTwoValues(&someString, &anotherString)
// 変数someStringは「world」、notherStringは「hello」
####デフォルト引数
func isValidService(serviceName: String , accountType: String = "none") -> Bool {
...
return true
}
let isValid = isValidService("Picture") // isValidService("Picture", "none"')と同値
代入
####通常
let b = 10
var a = 5
a = b
// aの値は10になります
enum
####定義
enum CompassPoint {
case North
case South
case East
case West
}
####呼び出し
var point : CompassPoint = .East
配列
####リテラル
[value 1, value 2, value 3]
####String型の配列
var shoppingList: [String] = ["Eggs", "Milk"]
####Int型の変数から配列を生成
var a : Int = 100
var b : Int = 200
var numbers = [a, b] //-> [100, 200]
辞書
####リテラル
[key 1: value 1, key 2: value 2, key 3: value 3]
Extension クラス拡張
extension Double {
var km: Double { return self * 1_000.0 }
var m: Double { return self }
var cm: Double { return self / 100.0 }
var mm: Double { return self / 1_000.0 }
var ft: Double { return self / 3.28084 }
}
let oneInch = 25.4.mm
println("One inch is \(oneInch) meters")
// One inch(25.4.mm) は 0.0254 meters
let threeFeet = 3.ft
println("Three feet is \(threeFeet) meters")
// prints Three feet(3.ft) は 0.914399970739201 meters
便利な数値リテラル
var money : Int = 2_000_000
Initialization
initキーワード
Objective-Cでいう - [NSObject init]
呼び出す場合は HogeClass() という風になる
Deinitialization
deinitキーワード
Objective-Cでいうdeallocのようなもの。
classオブジェクトしか利用できない
getのプレフィックスについて
やはりObjective-Cの理念としてメソッド名にgetのPrefixはつけていない模様
キャスト
var hogeNum : Int = 10
var hogeNumStr : String = String(hogeNum)
継承
####親クラス
class Vehicle {
var numberOfWheels: Int
var maxPassengers: Int
func description() -> String {
return "(numberOfWheels) wheels; up to (maxPassengers) passengers"
}
init() {
numberOfWheels = 0
maxPassengers = 1
}
}
####子クラス
class Bicycle: Vehicle {
init() {
super.init()
numberOfWheels = 2
}
}
####メソッドオーバーライド
class Car: Vehicle {
var speed: Double = 0.0
init() {
super.init()
maxPassengers = 5
numberOfWheels = 4
}
override func description() -> String {
return super.description() + "; "
+ "traveling at \(speed) mph"
}
}
####プロパティオーバーライド
class SpeedLimitedCar: Car {
override var speed: Double {
get {
return super.speed
}
set {
super.speed = min(newValue, 40.0)
}
}
}
####オーバーライド防止
@final修飾子をつけることによってサブクラスがオーバーライドすると
コンパイラがエラーにしてくれます
クラス
####定義
class Hoge {
// Hoge コンストラクタ
init(){
// 生成処理
}
// Hoge デコンストラクタ
deinit(){
// 破棄処理
}
}
####プロパティ
プロパティは定義して初期値を設定しない場合は
コンストラクタ内で初期値を設定しなければエラーとなる
#####初期値を設定する場合
class Car {
var numberOfWheels : Int = 4
}
#####初期値を設定しない場合
class Car {
var numberOfWheels : Int
init(){
numberOfWheels = 4
}
}
ゲッター、セッターも定義ができる
#####プロパティ内でゲッター定義
class Car {
var numberOfWheels : Int {
get {
return 4
}
}
}
####呼び出し
var hoge : Hoge = Hoge()
####クラスメソッド定義
class Fuga {
class func some() -> String {
return "did it."
}
}
####クラスメソッド呼び出し
Fuga.some() //-> did it.
クロージャ
####通常
let sum = {
(a:Int, b:Int)->Int in
return a+b
}
sum(1+2) //-> 3
####返り値型省略
let sum = {
(a:Int, b:Int) in
return a+b
}
sum(1+2) //-> 3
タイプ
####独自タイプ定義
typealias Vector = (Double, Double, Double)
let playerVector = (10, 20, 50)
名前空間
ProjectのBuildTargetごとに名前空間が付く
is 演算子
Objective-Cでいうところの
- - [NSObject isKindOfClass]
- - [NSObject isConfirmToProtocol]
そのオブジェクトがクラスまたはプロトコルに準拠しているかをチェックします
if object is UILabel {
// ラベルです
} else {
// ラベルではありません
}
##3 C言語との連携
C言語のプリミティブ型のSwift対応型表
C言語型 | Swift型 |
---|---|
bool | CBool |
char, signed char | CChar |
unsigned char | CUnsignedChar |
short | CShort |
unsigned short | CUnsignedShort |
int | CInt |
unsigned int | CUnsignedInt |
long | CLong |
unsigned long | CUnsignedLong |
long long | CLongLong |
unsigned long long | CUnsignedLongLong |
wchar_t | CWideChar |
char16_t | CChar16 |
char32_t | CChar32 |
float | CFloat |
double | CDouble |
C言語対応Swift型をSwift型に変換
C言語対応Swift型変数 | 変換 | 変換Swift型 |
---|---|---|
cValue : CBool | Bool(cValue) | Bool |
cValue : CChar | String.fromCString(UnsafePointer(cValue)) | String |
cValue : CUnsignedChar | String.stringWithCString(UnsafePointer(cValue), encoding: someEncoding) | String |
cValue : CShort | Int16(cValue) | Int16 |
cValue : CUnsignedShort | UInt16(cValue) | UInt16 |
cValue : CInt | Int32(cValue) | Int32 |
cValue : CUnsignedInt | UInt(cValue) | UInt |
cValue : CLong | Int(cValue) | Int |
cValue : CUnsignedLong | UInt(cValue) | UInt |
cValue : CLongLong | Int64(cValue) | Int64 |
cValue : CUnsignedLongLong | UInt64(cValue) | UInt64 |
cValue : |
C言語のポインタ型のSwift対応型表
C言語ポインタ型 | Swift型 |
---|---|
const void * | CConstVoidPointer |
void * | CMutableVoidPointer |
const 型 * | CConstPointer<型> |
型 * | CMutablePointer<型> |
void * | COpaquePointer |
型 * | UnsafePointer<型> |
型 * const * | CConstPointer<型> |
型 * __strong * | CMutablePointer<型> |
型 ** | AutoreleasingUnsafePointer<型> |
4 Objective-Cとの連携/比較
NS_ENUM定義とSwiftのenum定義比較
Objective-C
typedef NS_ENUM(NSInteger, UITableViewCellStyle) {
UITableViewCellStyleDefault,
UITableViewCellStyleValue1,
UITableViewCellStyleValue2,
UITableViewCellStyleSubtitle
};
Swift
enum UITableViewCellStyle: Int {
case Default
case Value1
case Value2
case Subtitle
}