LoginSignup
59
56

More than 5 years have passed since last update.

Swiftとはどのような言語か?

Last updated at Posted at 2014-08-31

※諸事情によりはてブロから転載

作成日
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
}

59
56
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
59
56