SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

アップルの新プログラミング言語「Swift」を探検しよう

Swiftのパワフルな記述力が秘められた
「関数」と「クロージャ」

アップルの新プログラミング言語「Swift」を探検しよう 第2回


  • X ポスト
  • このエントリーをはてなブックマークに追加

関数のさまざまな引数

 Swiftでは、Objective-Cより進歩した引数宣言が可能になっています。それらを紹介しましょう。

外部引数名宣言

 Objective-Cのメソッドの多くは、2つ目の引数以降に、引数を説明するようなラベルがつけられていました。

NSObject *obj = [NSObject new];
[obj performSelector: @selector(description)
          withObject: nil
          afterDeley: 1.0f]; //各引数をラベルで説明する

 Swiftにも、関数呼び出しの際、説明的に引数にラベルを付与できる外部引数名宣言があります。先ほどのコード例で見たmultiprint関数を、外部引数名宣言を使って宣言しなおしてみましょう。

func multiprint(string content: String, withTimes times: UInt) {
    for _ in 1...times {
        print(content)
    }
}
multiprint(string: "Good!", withTimes: 10)

 内部引数「content」「times」の前に、それぞれ「string」「withTimes」というラベルがつけられています。外部(関数を呼び出す側)から見て、関数の意味がわかりやすくなったと思いませんか。

外部引数名宣言の略記法

 Swiftには、「#」を使った外部引数名宣言の略記法があります。先ほどのmultiprint関数を略記法で宣言すると、次のとおりになります。

func multiprint(#string: String, #withTimes: UInt) {
    for _ in 1...withTimes {
        print(string)
    }
}

 このコードは、次のように宣言するのと同等です。

func multiprint(string string: String, withTimes withTimes: UInt) {
    for _ in 1...withTimes {
        print(string)
    }
}

 つまり、略記法では、外部引数名と内部引数名が等しく宣言されます。Objective-Cに比べ、宣言もしやすくなりましたね。

引数のデフォルト値

 Swiftの関数には、引数のデフォルト値も設定できるようにもなりました。引数宣言の後に、デフォルト値を付与するだけです。

func multiprint(#string: String, withTimes: UInt = 5) {
    for _ in 1...withTimes {
        print(string)
    }
}
multiprint(string: "Good!! ") // Good!! Good!! Good!! Good!! Good!!
multiprint(string: "Well Done!! ", withTimes: 3) // Well Done!! Well Done!! Well Done!! 

 

可変長引数

 引数の型宣言の後に...をつけることで、可変長引数を持った関数を宣言することができます。

func concatStrs(strs: String...) -> String {
    var mStr = ""
    for str in strs {
        mStr += str
    }
    return mStr
}
concatStrs("Good", " ", "night", " ", "!!") // Good night !!

 このとき、引数strsはArray型として扱えます。

 一般に、T型の値を可変長引数としてT...で宣言することで、関数内部ではArray<T>として扱うことができます。va_listなどのC言語のマクロを駆使して可変長引数の関数を扱っていたこれまでと比べると、シンプルに実装できそうです。

 なお、可変長引数を扱う際には、次の2点を満たさなくてはならないことに注意してください。

  • 引数宣言の末尾であること
  • 複数の可変長引数は1つの関数に宣言しないこと

 また、関数の引数は、デフォルトでは定数として宣言されます。そのため、関数の引数に代入しようとすると、letで宣言された変数に代入しようとするときと同じくエラーになります。引数を関数内で変数として扱うには、引数宣言の前にvarを置きます。

 次のbuildString関数は、先ほどの例のconcatStrs関数と内部の処理はほとんど同じですが、引数宣言の前にvarを置くことで、concatStrs関数の先頭で行っていた変数宣言(var mStr = "")を省くことが可能になります。

func buildString(var string: String, #withStrings: [String]) -> String {
    for str in withStrings {
        string += str
    }
    return string
}
buildString("a", withStrings:["r", "ra", "y"]) // "array"

 引数宣言の前にinoutキーワードを置くと、C言語の関数におけるポインタ引数のように値型を扱うことが可能になります。次のコードでは、関数内部でinoutのついた引数を、あたかもポインタのように扱ってString値を入れ替えています。

func swapStr(inout aStr: String, inout bStr: String) {
    let tempAStr = aStr
    aStr = bStr
    bStr = tempAStr
}
var food = "food"
var human = "human"
println(food + " made " + human) // "food made human"
swapStr(&food, &human)
println(food + " made " + human) // "human made food"

次のページ
関数型を値・引数・返り値として扱う

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
アップルの新プログラミング言語「Swift」を探検しよう連載記事一覧

もっと読む

この記事の著者

yad(ヤド)

クラスメソッド株式会社のアプリケーションエンジニア。iPhoneアプリケーションの開発に2年以上従事している。開発に使用するObjective-Cのみならず、関数型言語Haskellや機械学習などにも関心がある。「Developers.IO」に寄稿した記事の一覧

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/7869 2014/07/09 21:05

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング