詳解Swift改訂版(02)〜関数

2016. 12. 28
この記事は詳解 Swift 改訂版(初版第1刷)を元に、Xcode 8.2.1(Swift 3.0.2)下における差異を記述しています。



CHAPTER 02 関数



●2.1 関数定義の基本


・関数定義の概要

List2-1 において、関数の引数のラベルは第1引数でも必要になりました。

func count(n: Int) -> Int {
    total += n
    return total
}

count(10)        // error: missing argument label 'n:' in call

Qiita/Xcode 8 Release Notes 日本語翻訳メモ」によると、Swift 3 で関数の引数は全ての引数でラベル付けされることになったようです。

これに関しては「Xcode 8 Release Notes(Xcode 8.0/Swift/New Features)」に、その旨の記述があります。

「関数の引数は現在、全ての関数の引数に渡って一貫したラベル付けを行うようになりました。
このアップデートでは第1引数の宣言が、これまでの第2以降の引数の動作と一致するようになりました。

以前に書かれたコードでは、

func Resolved Issues(x: Int, y: Int) {}
Resolved Issues(1, y: 2)

func bar(a a: Int, b: Int) {}
bar(a: 3, b: 4)

となっていましたが、現在は次のように記述します。

func Resolved Issues(_ x: Int, y: Int) {}
Resolved Issues(1, y: 2)
func bar(a: Int, b: Int) {}
bar(a: 3, b: 4)

(
SE-0046)」

したがって関数 count の呼び出しは以下のようになります。

count(n: 10)


・外部引数名

上記の通り関数は全ての引数でラベル付けされるようになりましたので、これまでの Objective-C のメソッド記法のように関数名に第1引数の意味を含める必要は無くなったと思われます。
今後はシンプルな関数名で構わないでしょう。

List2-2 を例にすると、

func buyProduct(product:Int, price:Int, quantity:Int) {
    print("Product:\(product), amount = \(price * quantity)")
}

buyProduct(product: 19090, price: 180000, quantity: 1)        // Product:19090, amount = 180000

関数名に第1引数の意味を含み、且つ第1引数のラベルもあって冗長になりますので、関数名から第1引数の意味を取り除いた方がいいでしょう。

func buy(product:Int, price:Int, quantity:Int) {
    print("Product:\(product), amount = \(price * quantity)")
}

buy(product: 19090, price: 180000, quantity: 1)        // Product:19090, amount = 180000

また今回の例で言えば、関数名 buy だけでは単純すぎて心許なく、引数の product はカタログ番号であることから、関数名をそのままに第1引数名を number とする手もあるでしょう。

func buyProduct(number:Int, price:Int, quantity:Int) {
    print("Number:\(number), amount = \(price * quantity)")
}

buyProduct(number: 19090, price: 180000, quantity: 1)        // Number:19090, amount = 180000

もしくは「_」で第1引数の外部引数名を省略することで、これまでと同じ挙動にすることもできます。

func buyProduct(_ product:Int, price:Int, quantity:Int) {
    print("Product:\(product), amount = \(price * quantity)")
}

buyProduct(19090, price: 180000, quantity: 1)        // Product:19090, amount = 180000

いずれにせよ、これまでの記法には再考の余地があります。

※ 以降において、第1引数のラベル付けに関する修整については、分かり易さのために「_」で呼び出し時の外部引数名を省略することにし、特別な理由がなければ説明を割愛します。


・外部引数名の指定と省略

上記の通り第1引数も自動的に外部引数名が付与されることになりましたが、

func area(h:Double, w:Double) -> Double {
    return h * w
}

let a = area(h: 10.0, w: 12.5)

これまでと同様、内部引数名と別途に外部引数名を指定することもできます。

func area(height h:Double, width w:Double) -> Double {
    return h * w
}

let a = area(height: 10.0, width: 12.5)



●2.2 関数定義におけるさまざまな設定


・inout 引数

List 2-3 において、inout 引数でエラーが出るようになりました。

func mySwap(inout _ a:Int, inout _ b:Int) {        // 'inout' before a parameter name is not allowed. place it before the parameter type instead

Qiita/Xcode 8 Release Notes 日本語翻訳メモ」によると、Swift 3 で inout 引数は : の後ろに書くことになったようです。

これに関しては「Xcode 8 Release Notes(Xcode 8.0/Swift/New Features)」に、その旨の記述があります。

「inout 属性の場所が : の後ろ且つ引数型の前に移動されています。
例えば以前に書かれたコードでは、

func Resolved Issues(inout x: Int) {
}

ですが、現在は次のように記述する必要があります。

func Resolved Issues(x: inout Int) {
}

(SE-0031)」


したがって関数 mySwap の引数は以下のようになります。

func mySwap(_ a: inout Int, _ b: inout Int) {


・関数の引数に規定値を指定する

List2-4 の関数 setFont の実行結果の例で、規定値を指定した引数の順序を入れ替えた場合にエラーが出るようになりました。

setFont(name: "Times", bold:true, size:18.0)        // error: argument 'size' must precede argument 'bold'

Qiita/Xcode 8 Release Notes 日本語翻訳メモ」によると、Swift 3 で規定値を持つ引数は宣言順に指定することになったようです。

これに関しては「Xcode 8 Release Notes(Xcode 8.0/Swift/New Features)」に、その旨の記述があります。

「デフォルト値を持つ関数の引数は、現在宣言順に指定する必要があります。
呼び出し時に提供する引数の位置は、常に宣言された順序で関数に渡す必要があります。

func requiredArguments(a: Int, b: Int, c: Int) {}
func defaultArguments(a: Int = 0, b: Int = 0, c: Int = 0) {}

requiredArguments(a: 0, b: 1, c: 2)
requiredArguments(b: 0, a: 1, c: 2)        // error
defaultArguments(a: 0, b: 1, c: 2)
defaultArguments(b: 0, a: 1, c: 2)        // error

指定された引数が宣言の順序に従う限り、デフォルト値を持つ任意のラベル付き引数を省略することができます。

defaultArguments(a: 0)        // ok
defaultArguments(b: 1)        // ok
defaultArguments(c: 2)        // ok
defaultArguments(a: 1, c: 2)        // ok
defaultArguments(b: 1, c: 2)        // ok
defaultArguments(c: 1, b: 2)        // error

(SE-0060)」


したがって関数 setFont の引数は以下のようになります。

setFont(name: "Times", size:18.0, bold:true)        // Times 18.0 [B]


・引数の値を処理中に変更できるようにする

List2-6 の関数 dayOfWeek において、引数への var 修飾語の付与はエラーが出るようになりました。

func dayOfWeek(var _ m:Int, _ d:Int, var year y:Int = 2016) -> Int {        // error: parameters may not have the 'var' specifier

Qiita/Xcode 8 Release Notes 日本語翻訳メモ」によると、Swift 3 で関数の引数で var が使えなくなったようです。

これに関しては「Xcode 8 Release Notes(Xcode 8.0/Swift/New Features)」に、その旨の記述があります。

「var はもはや関数の引数属性として認められません。
コンパイラは関数本体にシャドウコピーを作成するための修正を提供します。
例えば以前に書かれたコードが、

func Resolved Issues(var x: Int) {
}

となっていた場合、現在は次のように記述する必要があります。

func Resolved Issues(x: Int) {
  var x = x
}

(
SE-0003)」

したがって関数 dayOfWeek の引数指定は以下のようになります。

func dayOfWeek(_ m:Int, _ d:Int, year y:Int = 2016) -> Int {
    var m = m, y = y

また本文中で「変更しないことを明示するために let という修飾語を使うことができます。」とありますが、「Qiita/Xcode 8 Release Notes 日本語翻訳メモ」にSwift 3で無駄な let は削除されたとあり、「Xcode 8 Release Notes(Xcode 8.0/Swift/New Features)」に、その旨の記述があります。

「let はもはや関数の引数属性として認められません。
コンパイラは関数の宣言から削除するための修正を提供します。(
SE-0053)」

例えば関数 dayOfWeek の引数 d に let を指定すると警告が出ます。

func dayOfWeek(_ m:Int, let _ d:Int, year y:Int = 2016) -> Int {        // 'let' as a parameter attribute is not allowed


・返り値を必ず使うための指定

返り値を伴う関数に @warn_unused_result 属性を指定すると警告が出るようになりました。

@warn_unused_result        // 'warn_unused_result' attribute behavior is now the default
func dayOfWeek(_ m:Int, _ d:Int, year y:Int = 2016) -> Int {

Tomorrow Never Comes./[Swift]関数の返り値を使わない時は」によると、Swift 3 から関数の返り値を使用しない場合はデフォルトで警告が出るようになったため、@warn_unused_result は不要になったようです。

逆に返り値を使用しないことを明示するには @discardableResult 属性を指定することになります。

ただしプレイグラウンドでは、返り値を伴う関数を返り値を使用しない形で実行しても警告が出ないようなので注意が必要です。



Qiita/Xcode 8 Release Notes 日本語翻訳メモ

Tomorrow Never Comes./[Swift]関数の返り値を使わない時は

詳解Swift 第3版(Amazon)
 






Bose QuietComfort 20
0 Comments
Leave a comment
管理者にだけ表示を許可する
Top
0 Trackbacks
Top
Calendar
08 | 2017/09 | 10
Sun Mon Tue Wed Thu Fri Sat
- - - - - 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Recent Articles
iTunes


Swift
Categories
Tips
Profile

水月杏香

Author:水月杏香
永遠の初心者プログラマ。

Wish List
WACOM


ARC
Technical Q&A
情報プロパティリストキー
Start Developing iOS Apps Today
BOSE

Bose QuietComfort 20
Reference
NSApplicationDelegateプロトコル
NSArrayクラス
NSAutoreleasePoolクラス
NSBundleクラス
NSBundle UIKit追加分
NSCalendarクラス
NSCoderクラス
NSCodingプロトコル
NSCopyingプロトコル
NSDataクラス
NSDateクラス
NSDateFormatterクラス
NSDictionaryクラス
NSEntityDescriptionクラス
NSEnumeratorクラス
NSErrorクラス
NSExceptionクラス
NSFetchRequestクラス
NSFileHandleクラス
NSFileManagerクラス
NSIndexPathクラス
NSIndexPath UIKit追加分
NSKeyedArchiverクラス
NSKeyedUnarchiverクラス
NSKeyValueCodingプロトコル
NSLocaleクラス
NSManagedObjectクラス
NSManagedObjectContextクラス
NSManagedObjectModelクラス
NSMutableArrayクラス
NSMutableCopyingプロトコル
NSMutableDictionaryクラス
NSMutableSetクラス
NSNotificationクラス
NSNotificationCenterクラス
NSNullクラス
NSNumberクラス
NSObjectクラス
NSObject UIKit追加分
NSObjectプロトコル
NSPersistentStoreクラス
NSPersistentStoreCoordinatorクラス
NSPredicateクラス
NSPropertyListSerializationクラス
NSRunLoopクラス
NSSetクラス
NSStringクラス
NSString UIKit追加分
NSTimerクラス
NSTimeZoneクラス
NSURLクラス
NSURLProtectionSpaceクラス
NSURLRequestクラス
NSUserDefaultsクラス
NSValueクラス

UIActionSheetクラス
UIActionSheetDelegateプロトコル
UIActivityIndicatorViewクラス
UIAlertViewクラス
UIAlertViewDelegateプロトコル
UIApplicationクラス
UIApplicationDelegateプロトコル
UIBarButtonItemクラス
UIBarItemクラス
UIButtonクラス
UIColorクラス
UIControlクラス
UIDatePickerクラス
UIDeviceクラス
UIEventクラス
UIFontクラス
UIGestureRecognizerクラス
UIImageクラス
UIImageViewクラス
UIKit Function
UILabelクラス
UINavigationControllerクラス
UINavigationItemクラス
UIPickerViewクラス
UIPickerViewDataSourceプロトコル
UIPickerViewDelegateプロトコル
UIPinchGestureRecognizerクラス
UIResponderクラス
UIScreenクラス
UIScrollViewクラス
UISearchBarクラス
UISearchBarDelegateプロトコル
UISegmentedControlクラス
UISliderクラス
UISwipeGestureRecognizerクラス
UISwitchクラス
UITableViewクラス
UITableViewCellクラス
UITableViewControllerクラス
UITableViewDataSourceプロトコル
UITableViewDelegateプロトコル
UITapGestureRecognizerクラス
UITextFieldクラス
UITextFieldDelegateプロトコル
UITextInputTraitsプロトコル
UITextViewクラス
UITextViewDelegateプロトコル
UIToolbarクラス
UITouchクラス
UIViewクラス
UIViewControllerクラス
UIWebViewクラス
UIWebViewDelegateプロトコル
UIWindowクラス

AVAudioPlayerクラス
AVAudioPlayerDelegateプロトコル

CADisplayLinkクラス
CAEAGLLayerクラス
CALayerクラス

CGAffineTransform
CGBitmapContext
CGColor
CGColorSpace
CGContext
CGGeometry
CGImage
CGPath

EAGLContextクラス
EAGLDrawableプロトコル

Foundation Constants
Foundation Data Types
Foundation Functions

MPMediaItemクラス
MPMediaItemArtworkクラス
MPMediaPlaylistクラス
MPMediaPropertyPredicateクラス
MPMediaQueryクラス
MPMusicPlayerControllerクラス

Randomization Services

System Sound Services
Amazon


OpenGL ES
SQLite
Monthly Archives
Recent Comments
Recent TrackBacks
RSS Link
Visitors
QR Code
QR