詳解Swift(1)〜Swiftでプログラミング

2016. 06. 01
(※2016年6月1日追記:この記事は詳解 Swift(初版第1刷)を元に、Xcode 7.3.1(Swift 2.2)下における加筆・修正を行っています。)



Objective-C時代に開発者の必携だった「詳解 Objective-C 2.0 第3版」の著者である荻原剛志さんが書かれたSwift本「詳解 Swift」が昨年満を持して発売されました。(2015年12月25日にSwift2に対応した「詳解 Swift 改訂版」が発売されています。)

無料で読めるウェブサイトの入門記事などでは理解し難かった点が丁寧に解説されており、第1章を読んだだけでも買ってよかったと思えるほどの良本で、今後の開発者にとって必携と言えるでしょう。

この本1冊でiOSアプリを開発できるわけではありませんが、初心者の方は入門書1、2冊と「詳解Swift」を一緒に買って勉強するのが良いと思います。



CHAPTER 01 Swiftでプログラミング



●1.1 データ型と変数


・型パラメータ

リストで配列のパラメータ付き型指定の部分は、ArratではなくArrayです。

var a : Arrat<Int>        // error: use of undeclared type 'Arrat'
var a : Array<Int>



●1.2 制御構文


・while文

List1-1 の while 文中の前置インクリメント部分に「'++'は Swift 3 で削除するため廃止になりました」と警告が出るようになりました。

Xcode 7 Release Notes(Xcode 7.3 Release Notes/New Features/Swift)」に、++/-- 演算子に関する記述があります。


「++ と -- 演算子は Swift 3.0 で削除する予定のため廃止されました。
その代わりとして、整数または浮動小数点型では x += 1 を、インデックス型では x = x.successor() を使用してください。(23708702)」


したがって " ++i " は " i += 1 " に置換することになります。

8037.png


・do-while文

Xcode 7 Release Notes(Xcode 7.0 Release Notes/Swift/Swift Standard Library)」に、Xcode 7.0/Swift 2.0からdo/whileループはrepeat/whileに名称変更されたと記述があります。

「do/whileループは、先頭のキーワードからその文がループであるかどうかを明示するために、repeat/whileに名称変更されました。

Swift 1.2:

do {
...
} while <condition>

Swift 2.0:

repeat {
...
} while <condition>

(20336424)」



・print文

List1-2のdo-while文は上記の理由により、記述すると「'do-while' statement is not allowed: use 'repeat-while' instead」とrepeat-whileに変更するようにエラーが出ます。

またprintln関数も「error: 'println' has been renamed to 'print'」というエラーが出ます。

このprint / println関数についても「Xcode 7 Release Notes(Xcode 7.0 Release Notes/Swift/Swift Standard Library)」に、Xcode 7.0/Swift 2.0から変更がなされていると記述があります。

「printおよびdebugPrint関数が改善されています:

 ・両関数は可変長引数となっており、一度の呼び出しで任意の数の項目を出力することができます。
 ・項目を分割することができるように、separator: String = " " が追加されました。
 ・appendNewline: bool = true は terminator: String = "\n" に置き換えられました。
  この変更により、print(x, appendNewline: false) はprint(x, terminator: "") と表します。
 ・変化する出力ストリームに対応するため、引数ラベル toStream がストリーム引数に追加されました。

 Swift 1.2からのprintln関数は削除されました。」


つまり「いものやま。/Xcode 7にアップデートしてみた。」で説明されているように、println()関数は廃止され、print()関数は自動で改行されるようになりました。

・改行無しのコンソール出力:print(x)    → print(x, terminator: "")
・改行有りのコンソール出力:println(x) → print(x)

したがってList1-2は下記のように修正することになります。

var n = 7
repeat {
    print("\(n) ", terminator: "")
    if n % 2 == 0 {
        n /= 2
    }else {
        n = n * 3 + 1
    }
}while n > 1
print(n)

ただしXcode 6.xまではAssistant Editorに出力されていたprint() / println()関数のコンソール出力は、Xcode 7.0から(Assistant Editorには何も出力されず)Debug Areaに出力されるようになったので注意が必要です。
(「iPhoneDev.tv/Xcode 7 moves Playgrounds Console Output and breaks print() and println()」参照)

以降の例においてもprint() / println()関数は多用されているので、その都度修正してください。


・for文

旧println()関数では空の改行を「println()」と記述していましたが、print()関数では「print()」ではなく「print("")」と空引数を渡す必要があるようです。

Xcode 7.3.1では空改行する際に空引数を渡さず単純に「print()」と記述するだけでも警告は出ないようです。
(以前の記法「print("")」でも問題ありません)

println()        // error: 'println()' is unavailable: use print("")
print()          // error: 'print' is unavailable: Please wrap your tuple argument in parentheses: 'print((...))'
print("")

また先述の前置インクリメントと同様に List1-3 の後置インクリメントも警告が出るため、" i++ " は " i += 1 " に置換することになります。

8038.png

しかしインクリメント演算子を修正すると今度は「Swift の将来のバージョンで削除されるため、C(言語)様式の文は推奨されない」と警告が出ます。

8039_.png   

この件に関しては「Qiita/Swift 初心者がまとめる Xcode 7.3 で Warning になった Swift の文法」や「Qiita/既存アプリの Xcode 7.3 + Swift 2.2 対応」などで for-in 文への修正方法が提案されています。

for var i = 1; i <= 9; i += 1 {        // C-style for statement is deprecated and will be removed in a future version of Swift
    for var j = 1; j <= 9; j += 1 {        // C-style for statement is deprecated and will be removed in a future version of Swift

for i in 1...9 {
    for j in 1...9 {

ただ for-in 文では List1-4 のように初期化部で複数の変数を初期化するというような記述はできないので、普通に分けて記述するしかないでしょうか?

for var i=0, m=1; i < 32; i++, m *= 2 {        // '++' is deprecated: it will be removed in Swift 3
// C-style for statement is deprecated and will be removed in a future version of Swift

    print("\(i)  \(m)")
}

var m = 1
for i in 0..<32
{
    print("\(i)  \(m)")
    m *= 2
}


・for-in文

List1-5のfor-in内の文で、String型イニシャライザで変数chを初期化する部分は小文字のstringではなく型名のStringです。

result = string(ch) + result    // error: use of unresolved identifier 'string'

result = String(ch) + result

またSwift 2.0以降、文字列から一文字ずつ取り出すfor-in文はエラーが出るようになりました。

for ch in str {        // error: type 'String' does not conform to protocol 'SequenceType'

これは「String型はSequenceTypeプロトコルに準拠していません」(「articles of samekard/Swiftのコンパイルエラー寄せ集め」参照)というエラーです。
SequenceTypeとは本書の335頁に「for-in文で繰り返しができる型を表すプロトコル」とあります。

これに関しては「Xcode 7 Release Notes(Xcode 7.0 Release Notes/Swift/Swift Standard Library)」に、Xcode 7.0/Swift 2.0からString型の変更について記述があります。

「String no longer conforms to SequenceType in order to prevent non-Unicode correct sequence algorithms from being prominently available on String. To perform grapheme-cluster-based, UTF8-based, or UTF-16-based algorithms, use the .characters, .utf8, and .utf16 projections respectively.(抄訳:StringはSequeceTypeに準拠しなくなりましたので、書記素クラスタ単位で実行するにはそれぞれ.characters、.utf8、.utf16プロパティを使ってください。)」

したがって、List1-5のfor-in文の式は以下のようになります。

for ch in str.characters {


・ラベル付きのループ文

List1-6 に関してですが、先述の通りインクリメント演算子や C 言語様式の for 文は使えなくなっていますので修正する必要があります。

let days = 31
let firstDay = 2
var w = 0

//for ; w < firstDay; w++ {    // '++' is deprecated: it will be removed in Swift 3
//for ; w < firstDay; w += 1 {    // C-style for statement is deprecated and will be removed in a future version of Swift

for w0 in 0..<firstDay {    // 外部変数 w の代わりに内部定数 w0 を設定
        print("   ", terminator: "")
        w = w0 + 1    // 内部定数 w0 をインクリメントして外部変数 w に代入
}

var d = 1
loop: while true {

//    for ; w < 7; w++ {    // '++' is deprecated: it will be removed in Swift 3
//    for ; w < 7; w += 1 {    // C-style for statement is deprecated and will be removed in a future version of Swift

        for _ in w..<7 {    // 内部定数は使用しないので '_' で省略
                print(d < 10 ? "  " : " ", terminator: "")
                print(d, terminator: "")

//        if ++d > days {    // '++' is deprecated: it will be removed in Swift 3
//        if d += 1 > days {    // error: binary operator '+=' cannot be applied to operands of type 'Int' and 'Bool'
//        if (d += 1) > days {    // error: cannot convert value of type '()' to expected argument type 'Int'
//        if ((d += 1) > days) {    // error: cannot convert value of type '()' to expected argument type 'Int'

        d += 1    // if 文の条件式内で二項演算することはできないようなので手前でインクリメント
        if d > days {    // 条件式は単純な比較
            print("")
            break loop
        }

    }
    print("")
    w = 0
}

1つ目の for/for-in 文ですが、元の for 文では w = 2 でループを抜けるのに対し、for-in 文では w0 = 1 の状態でループから抜けてしまうので、w に代入する際にインクリメントしていることに注意してください。
(式を閉区間にすると文が1つ余計に実行されてしまうので半開区間にしています)

それと if 文の条件式内で二項演算は括弧付きでもできないようなので、手前で d をインクリメントした後に if 文では単純な比較の条件式にしています。



●1.3 簡単な実行方法

List1-7 の for 文を for-in 文に修正する場合、範囲型の式は実数で表すとエラーになるので整数で表し、文中で Double 型にする必要があります。

var e = 0.0, t = 1.0
//for var i = 1.0; i <= 20.0; i++ {
//for i in 1.0...20.0 {    // error: binary operator '...' cannot be applied to two 'Double' operands

for i in 1...20 {
    e += t
    t /= Double(i)
}
print("e=\(e)")

なお変数の推移を表すグラフは現在エディタ領域に表示されるようになっています。

8040.png



Wikipedia/Swift (プログラミング言語)

IT用語辞典/リテラル

Wikipedia/キャメルケース

Wikipedia/コラッツの問題

いものやま。/Xcode 7にアップデートしてみた。

iPhoneDev.tv/Xcode 7 moves Playgrounds Console Output and breaks print() and println()

articles of samekard/Swiftのコンパイルエラー寄せ集め

Qiita/Swift 初心者がまとめる Xcode 7.3 で Warning になった Swift の文法

Qiita/既存アプリの Xcode 7.3 + Swift 2.2 対応

詳解 Swift 改訂版(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