見出し画像

iPhone アプリを自分でつくる 4.

今回の内容: 文字列、 数値、 ブール値と 比較演算について



変数に入れる文字列についてみていきます。

文字列のつくりかた

変数や定数に入れる文字はダブルクオテーション"で囲むことはすでに説明しましたが、ここで使用する文字列(つまり変数にアサインする文字)のことを string(ストリング)と呼びます。
stringは糸という意味ですが、文字が糸を通して横一列にぶらさがっているような、ひとつながりになっているイメージからきています。
Swiftでは文字をString型と呼び、その中に英数字記号、漢字はもちろん、絵文字もいれることができます。
なお、文字列の中にダブルクオテーションが入っている場合、Xcodeがstringの範囲がわからなくなってしまうので、\" のようにバックスラッシュを前に置く必要があります。
またstringを複数行にわたらせて表示させたいときは、2通りの記入方法があります。一つは改行記号として \n のようにバックスラッシュnを記入する方法です。
\nは改行として読み込まれます。もう一つは最初と最後にダブルクオテーションを三つづつ記入する方法です。

下の例文で確かめることができます。

var nextStation = "横浜"

let message = "Happy birthday! 🎂"            // 絵文字OK
   
let lastWord = "He said \"Thank you.\" and gone."   // "の前に\バックスラッシュをつける

let menu = "Burger\nPiza\nSushi"            // \n で改行する 

let movieTitle = """                     // """ をつかうと複数行を自然に書ける 
桐島、
部活やめるってよ
"""

print(nextStation)
print(message)
print(lastWord)
print(menu)
print(movieTitle)  

空文字(カラ文字)について

空文字とは文字が入っていないstringで、 var password = ""  のようにダブルクオテーションを二つ並べて書きます。
文字列が入る部屋は設置完了していていつでも使える状態ですが、
長さが0(ゼロ)の文字列と言ったりします。(ストリングですからね)
今後アプリを作成するときには、空文字を使用することがよくあります。
なお前回扱ったnil は何もない状態で取り扱いに注意が必要ですが、空文字は通常の文字と同じように取り扱います。
使い勝手がよいので最初に空文字をセットする、つまりString が入る部屋を用意しておき、必要なときにここに文字を入れていく方法はよく行われます。

var place = ""        // 変数 place に空文字をいれた
print(place)
place = "Disneyland"      // 文字をセットした
print(place)

文字列の連結

文字列はプラス記号+ を使って連結することができます。
+ の左右は半角スペースを入れてください。 

文字列に変数を挿入する

 文字列に変数を挿入することができます。
 \(変数)  のようにバックスラッシュの後に変数をカッコで記入すると文字列のあいだに変数が挿入されます。

Swiftの型について

Swiftはそれぞれの値やコードのまとまりは、型(Type)というものを持ちます。
文字列はString(ストリング)型を割り当てられます。
var streetName = "Sakura dori"  と書くとSwiftはstreetNameはString型と類推してあてはめてくれます。
また自分で型を明記しておく方法もあります。
var pet: String = "Dog"  のように変数(定数)のあとにコロンをつけてStringと書く方法です。
いっぽう変数の内容を入れずに、 let password: String  のように変数の型だけ明記すると何らかの文字が入るのを待っている状態文字が入ると変数として使える状態となります。
空文字が入っている場合は変数を使用できる状態になっていますが、この状態(まっている状態)とは違います。

例では変数dinner にまだ文字が入っていないためエラーメッセージ「変数dinnerがイニシャライズ(初期化)される前に使われています」と表示されています。
このようにString型の変数は文字(空文字含む)が入ると使えるようになりますが、使えるようにすることを初期化(イニシャライズ)すると言います。このような設定は通常に行いますので、少しづつ理解していきます。

String型の持つ機能

それぞれの型はそれぞれの機能を持っています。
Stringもたくさんの機能を持っていますが、少しだけ紹介します。

文字数を取得する
 文字列に .count(ドットカウント)をつけると文字数を取得できます。
 下の例では "Spaghetti"の文字列が入った変数 wordを word.count として
 letterCount変数にいれています。
 letterCount変数をprint()で確認すると数字の 9 が入っています。
 wordはStringですが変数にword.countをアサインすると数値がはいります。
 これをword.countは数値を返すとか戻すや数値をリターンすると言います。
 "Spaghetti".count も数値9 を返します

・ 並び替えた文字を取得する
次の例では 変数originalWordに文字"hokkaido"を入れた後、その変数に.sorted()を付加してmyCodedWordにアサインしています。.sorted() ドットソーティッド()は文字をabc順に並び替えたものを配列という型(後ほど学習します)で返しています
この後で print(originalWord) としてみてください。そのまま"hokkaido"と表示されます。.sorted()はもとの文字は変えずに並び替えた文字の配列を返すことが確認できます。

 ・文字が入っているか確認する
      String型に .isEmpty イズエンプティーをつけると、true または false を返します。空文字かまたはnil (ニル:なにもない状態)の時にtrue  を返します。一文字でも入っていればfalseを返します。
例ではplanToTripが空文字なのでplanToTrip.isEmpty は、trueを返します。
true, falseの 型についても後ほど学習します。

let planToTrip = ""

let checkEmpty = planToTrip.isEmpty

print(checkEmpty)   // true 

コメントの入力

コードに説明文などのメモを残したいことがあります。
行の最初に文字を // スラッシュ2本を記入するとコメントとしての扱いとなり、コードとしては翻訳されません。これをコメントアウトすると言います。
複数行をコメントアウトするときは、行をまとめて選択してから Ctrl + /  (コントロールを押しながらスラッシュ)で簡単にできます。
もう一つの簡単な方法は、コメントアウトの開始に /*  スラッシュ・アスタリスクを置き、終了ポイントで */ を置くことでその間の行をコメントアウトできます。
コメントは後からプログラムを見返したり、引き継いだりするときに重要な役割をはたします。

// コメントアウトした行
// コメントアウトした行
// コメントアウトした行

/*
スラッシュ・アスタリスクでコメントアウト開始
この行の間はすべてコメントアウトとなる。
アスタリスク・スラッシュでコメントアウト終了
*/

その他の文字

  文字列(string)は文字がつらなったものですが、その一文字づつはcharacter(キャラクター)と呼ばれます。
 Stringの機能にはCharacter型として文字を返すものもあります。



数字をあつかう1. (整数、 小数) 

数値は大きく分けて整数型と浮動小数点型に分かれます。

整数型

まずは整数型についてですが、整数は0, 1, 2, 3, 4, 5のように0以上の数と0, -1, -2, -3, -4, -5 のように0以下の数があります。
これらの数値は、Int型(イント型)と呼ばれます。IntとはInteger(インテジャー)の略で整数のことです。
プラス+符号、マイナス-符号はスペースを開けずに数値に付け加えます

Int型の持つ機能には、Int型の持つ最大数と最小数を返すものがあります。

let pointOne = 1
let minusOne = -1
let plusTwo = +2 

let maxInt = Int.max    // Int の最大数を返す
let minInt = Int.min   // Intの最小値を返す 

print(maxInt)
print(minInt)

ーーーーーーーーーーーーー

9223372036854775807
-9223372036854775808

    またInt型はさらに細かく分けるとInt8型、Int16型、Int32型、Int64型に分類できます。これは歴史的な背景でパソコンが8ビットから徐々に扱える桁数が増えてきたためです。今でも他のフレームワークとの関わりでこれらを使う場合があります。

 コードを記入していると桁数が多くて数値が読みにくい場合あります。
その場合は _アンダーバーを数値に入れると読みやすくなります。
Swiftはコードを翻訳するときに数値の間のアンダーバーは無視します。

let population = 1_000_000_000

print(population)
________________________
1000000000


小数点型
 
小数点を表すのに浮動小数点方式というものが使われています。
浮動小数点(Floating decimal point)というのは、コンピュータの性能を効率的に使えるように小数点の位置を数値によってずらして作られるので浮動(Floating)の名前がついています。
 歴史的な背景から、正確に表せる小数点の桁数を増やしてきました。以前はFloat型(フロート型)という32ビットの対応でしたが64ビットになったので倍精度(Double precision)になりDouble型の名がついています。
Double型の浮動小数点数はDouble型としての機能を持ちます。
なおアプリ作成においてはFloat型を使用する場面も多くでてきますが、ほとんどのケースでシステムが考えてDoubleを翻訳してくれます。

またこの浮動小数点というのは非常に複雑な方式で計算されており思わぬ誤差を生むので取り扱いに注意も必要です。
以下の足し算を実行して微妙な誤差を確認してください。不思議ですね!

let doubleA = 0.1
let doubleB = 0.2

let totalC = doubleA + doubleB

print(totalC)

// -----------------------------
0.30000000000000004

なお、Double型は15桁、Float型は6桁の精度が保証されるようです。
逆を言うとこの桁より小さい値について誤差が生じる可能性があるということですね。
通常の計算ではここまでの精度は必要ないので問題は発生しません。

参考までですが、Decimal型という型もあります。

let a: Decimal = 0.1
let b: Decimal = 0.2

let totalC = (a + b)
print(totalC)

// -----------------------------
0.3

このDecimal の計算は、整数に変換して計算し小数点に戻して返す、というような仕事をシステム内部でして誤差が現れないようにしています。
お金の計算などはDecimal の利用が推奨されます。

アップルの草創期にスティーブ・ジョブズは、固定小数点を使っていた天才プログラマーのスティーブ・ウォズニアックに「浮動小数点を使ってくれ」と懇願していたようです。
ウォズニアックは浮動小数点に避けられない誤差を嫌っていたのでしょうか?

数値の操作

 足し算、引き算などの計算方法をみていきます。
 
 足し算は + プラス記号、引き算は - 記号の左右に数値をおきますが、
 両側にスペースをはさみます。

   2つの数値を計算した結果を返します。

var myPlus = 1 + 2
var myMinus = 1 - 2

print(myPlus)
print(myMinus)
------------------------
3
-1

var testPlus = 2 +3    // エラー +記号の右にスペースがないのでうまく翻訳できません。
var testMinus = 2-3    // 両方ともスペースなしだと結果を返しますが、通常この方法は行いません。

 
掛け算は * アスタリスク、割り算は / スラッシュの左右に数値をおきますが、
両側にスペースをはさみます。

2つの数値を計算した結果を返します。


var myMultiple = 2 * 3
var myDevide = 4 / 2

print(myMultiple)
print(myDevide)
------------------------
6
2

var testMultiple = 2 *3  // エラー *記号の右にスペースがないのでうまく翻訳できません。
var testDevide = 4/2  // 両方ともスペースなしだと結果をかえしますが、通常この方法は行いません。


割り算の余り(剰余)計算

割り算の余りは % を使用します。
2つの数値を計算して結果を返します。
 4 % 2 であれば 0を返します。(4割る2の余りは0)
 5 % 3 であれば 2 を返します。(5割る3の余りは2)
割り算があれば当然そこから余りも計算できるのに、なぜわざわざ割り算余りを出す計算記号があるのか?ですか?

// % を使用しないでも余りは計算できる
var firstNum = 7
var secondNum = 3
var dividedAnswer = firstNum / secondNum   // 割り算の結果(整数でかえります: 2)

var modulo = firstNum - (dividedAnswer * secondNum)   // 7 - (2 * 3) = 1

print(modulo)  // 余りが計算できた

それは、プログラムでは割り算の余りを使用することがよくあるからです!
ある整数を2で割って余りが0だったら偶数、1だったら奇数と確認できます。
ある整数を3で割ると余りは、0か1か2のどれか3つのいずれかになります。
グーチョキパーに当てはめれば、じゃんけんゲームで使えます。
この性質をプログラミングの条件分岐に利用するのです。

let myCard = 100
let checkEven = myCard % 2
print(checkEven)
-----------
0
// 0となったのでmyCardは偶数とわかった

//---------------------------------------------

var jankenNumber = 50
let checkJanken = jankenNumber % 3
print(checkJanken)

//コンソール表示-----------
2

// jankenNumber にはランダムで数値が与えられるようにしておく
// 例えばcheckJanken 0はグー、1はチョキ、2はパーが表示されるように設定しておく
// 2がでたので、 パーを表示させてプログラムを進める

計算での注意点


計算をする際にはそれぞれの数値が同じ型でないとエラーとなります。
最初はすこし戸惑うかもしれませんが理解しておいてください。

下記の例は走った距離 10.0 と走った日数3をかけようとしたときのエラーです。

var runDistance = 10.0
var runDays = 3

var totalDistance = runDistance * runDays   // x Binary operator '*' cannot be applied to operands of type 'Double' and 'Int'

print(totalDistance)

ここで表示されたのは、計算記号 *はDouble型とInt型を同時に適用できませんよ、ということです。
Swiftは10.0という数値を確認すると「小数点があるからDouble型だな」、3を確認すると「Int型だな」というように必ず型を類推します。類推できないときにはエラーを出します。

下の例は、Swiftがどの型をアサインしたのかを確かめる方法です。
変数をtype(of:  変数) のようにすると変数の型を返します。
runDistance はDouble 、runDaysはIntでアサインされていることがわかります。

var runDistance = 10.0
var runDays = 3

var typeA = type(of: runDistance)
var typeB = type(of: runDays)

print(typeA)
print(typeB)

//コンソール表示-------------------------
Double
Int 

このような場合の対応ですが、両方ともDouble型にすれば計算できます。
方法は最初に型を明記する方法、型を類推させる方法、型を変換する方法があります。

型を明記しておく方法

// 型を明記しておく方法
var runDistance: Double = 10.0
var runDays: Double = 3       // 小数点はないがDoubleとするよ、と明記する

var totalDistance = runDistance * runDays

print(totalDistance)

型に合わせた数値を最初に入力しておく方法

// 小数点以下は使用しないが Double型がアサインされるようにする方法
var runDistance = 10.0
var runDays = 3.0    // 小数点以下は使用しないがDouble型がアサインされるようにした

var totalDistance = runDistance * runDays

print(totalDistance)

型を変換する方法
数値の型はDouble(数値の型)とするとDouble型を返すので変換して使用する

// Int型をDouble型に変換してから計算する方法
var runDistance: Double = 10.0
var runDays: Int = 3

var days = Double(runDays)   // runDaysをDoubleに変換して新しくdays変数をつくった

var totalDistance = runDistance * days   // 型変換したdays を使用して計算した

print(totalDistance)

数字をあつかう2. (比較演算子) 

比較の計算をあつかいますが、文字も比較することができるので紹介していきます。

比較演算子

比較演算子は2つの要素が等しいか等しくないか、より大きいか、小さいかなどを比較してその答えを真(しん)の場合はtrue(トゥルー)、偽(ぎ)の場合はfalse(フォルス)で返します
このtrue, false はBool型(ブール型またはブーリアン型)と呼ばれるもので、この型は、trueかfalseかどちらかいっぽうとなります。
このどちらかいっぽうになるというのはプログラミングでは非常に扱いやすいので
必ず使われる型です。

比較演算子の種類

 == イコール2つ 等しい  :左右に置かれた数値が等しい時はtrue
               そうでないときはfalse を返す 
   !=   エクスクラメーションとイコール 等しくない
              :左右に置かれた数値が等しくない時はtrue
               そうでないときはfalse を返す 
 >  左辺のほうが大きい     :左辺の方が大きい時true、
               そうでないときはfalse を返す
                                                      * 以下同様
   >= 左辺が右辺以上
   <   右辺の方が大きい
   <= 右辺が左辺以上
 これらの記号はBool型を返すということに注意してください。
 数学のように 10 > 5 である、だから〜 のような使い方はありません。
 10 > 5 はtrue ですし、10 < 5 は false となります。
  下の例では変数を介さずに返した結果をprintしています。

print(123 == 123)
//-------------------
true

print(123 == 124)
//-------------------
false

こんどは変数に返したものを print()してみます。

var isSame = 1_000 == 1000
var isNot = 10 != 20

let size = 100
var isBigger = size > 50
var isSmaller = size < 50

print(isSame, isNot, isBigger, isSmaller)

//コンソール表示--------------------------------------
true true true false   // 変数 isSmaller はfalseとなった

最初にこのような式をみたときは、1行の中に = や == がでてきて何とも変な感じがしますが、だんだんと慣れてきます。
実際にコードを書くのであれば、一番上の式は
var isSame = (1_000 == 1000)  のようにカッコを入れた方が読みやすいコードになり良いかもしれません。
Swiftは条件式== の結果を出してから=の左辺にあるisSame変数に答えを返します。これは各算術記号には計算する順番(priority)がつけてあるのでSwiftはカッコがなくても問題ありませんが、わたしたちは左から読んでいくのでそれを意識したほうが良いかもしれません。

次は文字列の比較もしてみます。
文字列が同じかどうかを比べるのはイメージがつきやすいかと思います。


let letter1 = "abc"        // 文字の代入
let letter2 = "abc"        // 文字の代入
var isSameLetters = (letter1 == letter2)  // 2つの変数に代入されている文字が等しいかの答えを代入
print(isSameLetters)

//コンソール表示------------------------------
true


let letter3 = "abc"
let letter4 = "def"
isSameLetters = (letter3 == letter4)
print(isSameLetters)

//コンソール表示------------------------------
false


let letter5 = "abc"
let letter6 = "def"
isSameLetters = (letter5 <= letter6)
print(isSameLetters)

//コンソール表示------------------------------
true

   上の例では文字列"abc"が"def"より小さいことがtrueとなっています。
 これは各文字は与えられている文字コード番号により表示されますが、小さい番号つまり早い順が小さいことになります。"あ" < "い" でtrueを返します。また、"abc" < "acb" はtrueを返します。

同じ型の数値で比較する
計算と同じように型が違うと「Int型とDouble型で型が違うので計算式が適用できません」とのエラーが表示されます。計算式と同じ方法で型を合わせてから比較することができます。

var distanceToA = 250
var distanceToB = 250.0

print(distanceToA == distanceToB)     x エラー Binary operator '==' cannot be applied to operands of type 'Int' and 'Double'

Bool型について

Bool型に ! エクスクラメーションマークがつくと反対のBool値を返します。
この場合  ! が否定演算子と呼ばれるものになります。
単純なことですが、勘違いも起きやすいのでどう使うか議論のあるところです。

var isOnSale = true 

if !isOnSale {           // 最初にtrue だったので !isOnSale はfalse を表す
   print("No go")
} else {
   print("Let's go")
}


// コンソール表示
Let's go


Bool型の機能のひとつに.toggle() (トグル)というものがあり、頻繁に使用されます。
トグルというのは、トグルスイッチと言ってボタンひとつで電源オン・オフを行うあの切り替え装置の機能のことを言います。
下の例で、trueがアサインされた変数isOnは.toggle()によってfalseになったことがわかります。

var isOn = true
isOn.toggle()

print(isOn)    // isOn自体を確認してみる

//コンソール表示--------------------
false          // falseに変わった


var b = isOn.toggle()     // エラー : Variable 'b' inferred to have type '()', which may be unexpected
print(b)

//コンソール表示--------------------
()      

  // 変数bは予期しない() 型ですよ、とでた。

.toggle()は変数そのものを切り替えます。
今度は変数isOn.toggle() を変数bに入れてみようとすると、注意書き⚠️として
「Variable 'b' inferred to have type '()', which may be unexpected」
「変数bは()型-何も返さないアクションする型-と推測したけど、この場所はおかしいですよ」と表示されました。()型はなんらかのアクションは起こす型であって、値を返すものを意味しません。

String型の機能で紹介した.sorted()は、string自体は変えずに変換した配列を返しましたsorted()() -> [Element] 型で配列を返す機能を持ちます。
いっぽう .sort() は、その配列そのものを変更する ()型 または () -> Void 型
です。
このように機能によって値を返すものや返さずにそのものを変更するものもあります。
メソッドが値を返すものか、そうでないのかはエラーがでてきたらわかりますし、
この後、SwiftUI を扱う際に確認の方法を取り上げます。
まずは、そのようなことがあるらしいぞ、と少しだけ頭の片隅に入れておけば十分です。


まとめ

文字列
 変数に入れる文字はstringと呼ばれます。
 ダブルクオテーションを文字の最初と最後につけString型の機能を持ちます。
 String型は連結や挿入ができます。
 コメントアウトする方法は2通り(・1行ごと ・行範囲)あります。

数値
 数値には整数Int型と浮動小数点Double型がある。
 整数はInt8型、Int16型、Int32型などさらに細かな型を持つ。
 浮動小数点型はFloat型も使われることがある。
 数値計算は同じ型どうしで計算する。違う型の場合は計算する際に
 同じ型になるように工夫する。

比較演算子
 比較演算子は2つの数値や文字を比べてBool値を返す。
 Bool型はtrue またはfalse のどちらかを返す重要な型。
 比較する場合は同じ型通ししかできないので必要に応じて型変換する。

Bool型
 Bool 型の機能にToggle() がある。
    Bool 型の頭に ! をつけると内容を反転できる。

次回第5回予定内容  コレクション型、条件式、ループです。
            めげずによろしくお願いします。



この記事が気に入ったらサポートをしてみませんか?