見出し画像

【じっくりSw1ftUI 20】Essentials第9章〜Playgroundで遊ぼう⑥ファンクションとかメソッドとかクロージャとか❶functionあれこれ

さてと、前回

で簡単な場合分け=switch文まで終わって、前回までで

本当に基本となるところの構文

までは、網羅できた様子👀なので、今回から

でもちろっと出てきた

ファンクションとかメソッドとかクロージャ

を、

略して、Essentials

のプロット(構成)に沿って、じっくりやってく〜〜〜🕺

今回からちょっと、応用編っぽくなってくるかなあ🧐

って感じなので、わからなくなってきたら、前回までのところを見返してね🙇‍♂️
では、早速


第9章をじっくり読んでく

  • ファンクション

  • メソッド

  • クロージャ

は、

オブジェクト指向(志向)言語として、より良いコードの書き方ができる

ものとして推奨されてて、

ここでその使い方をじっくりやってく

みたいなことが書かれてんね👀

次に、ファンクションとメソッドの違い

が書かれてて、

  • ファンクション:処理結果を返したり、パラメータを持つことができる

  • メソッド:次章以降で出てくる構造体とか列挙型を補完する機能

みたいなことが書かれてんね👀

ここまで読んだだけだと、プログラミングやったことがない人や苦手な人からしたら、

何のことやら

って感じだね💦

◾️ ファンクション(function)

⭐️構文

func 関数名 (パラメータ名1: パラメータ1の型,パラメータ名2: パラメータ2の型,...) -> 戻り値の型{
   //処理
}
ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー
・func:ここはコンパイラーが関数と認識する予約語、宣言文みたいな感じ
・関数名:関数の名前
・パラメータ名:設定する引数なんかの名前 
・パラメータの型:設定する引数なんかのデータ型
・戻り値の型:処理結果のデータ型
・処理:実行する処理

何気にいきなり

ラムダ式(アロー関数)

が出てきたね👀
(Swiftは、破壊的なコードの変更があった2→3の時代からしか知らないんだけど、オイラの記憶では、その頃にはすでに導入してたんだよね〜〜〜🤔)

1 一番簡単なコード

//基本
func myName9_1(){
    print("M_Kaku堂")
}

てな感じ👀で、実行してみても

みてのとおり処理結果の、オイラの名前は出てきてないんだよね〜〜〜👀
って、実はこれ当たり前の話で、

まだ、機能を宣言しただけで、実行を呼び出してないから

ってだけ。

2 呼び出し〜〜〜

//基本
//オイラの名前関数を宣言
func myName9_1(){
    print("M_Kaku堂")
}
//関数を呼び出して実行
myName9_1()

ってして実行ボタンをクリックすると、、、

てな感じ

3 パラメータを定義

//名前と年齢関数
func myNameAndAge9_2(myName:String,myAge:Int) ->String{
    return("オイラの名前は、\(myName)で歳は、\(myAge)歳")
}
print(myNameAndAge9_2(myName: "M_Kaku堂", myAge: 43))

なんかで実行すると

てな感じ

4 パラメータの操作

//名前と年齢関数の名前を小文字に〜〜
func myNameAndAge9_3(myName:String,myAge:Int) ->String{
    let lowerName9_3 = myName.lowercased()
    return("オイラの名前は、\(lowerName9_3)で歳は、\(myAge)歳")
}
print(myNameAndAge9_3(myName: "M_Kaku堂", myAge: 43))
てな感じで、

関数の中に、定数や変数なんかを宣言して、

パラメータの操作

をすることも可能🕺

5 変数や定数の初期値として利用

//変数の値として呼び出し〜〜〜
func myNameAndAge9_4(myName:String,myAge:Int) ->String{
    let lowerName9_4 = myName.lowercased()
    return("オイラの名前は、\(lowerName9_4)で歳は、\(myAge)歳")
}
//変数名にセット
var oilaNameAge9_4 = myNameAndAge9_4(myName: "M_Kaku堂", myAge: 43)
print("oilaNameAge9_4:\(oilaNameAge9_4)")
oilaNameAge9_4 = "岸田さんてんてこまい"
print(oilaNameAge9_4)
てなこともできる〜〜

6 長いのが嫌なら省略もできる

//パラメータ名を省略〜〜〜
func myNameAndAge9_5(_ myName:String,_ myAge:Int) ->String{
    var lowerName = myName.lowercased()
    return("オイラの名前は、\(lowerName)で歳は、\(myAge)歳")
}
//変数名にセット
var oilaNameAge9_5 = myNameAndAge9_5("M_Kaku堂", 43)
print("oilaNameAge9_5:\(oilaNameAge9_5)")
oilaNameAge9_5 = "松野さん寿司ざんまい"
print(oilaNameAge9_5)

って感じで、コードを変更すると、

てな感じ〜〜〜

ま、オイラは _ が可読性が落ちて嫌いだからあんまり実務でカッコつけるだけならおすすめはしないけどね。。。

7 キーワードも使えちゃう

//キーワード〜〜〜
func myNameAndAge9_6(oilaName myName:String,oilaAge myAge:Int) ->String{
    var lowerName = myName.lowercased()
    return("オイラの名前は、\(lowerName)で歳は、\(myAge)歳")
}
//変数名にセット
var oilaNameAge9_6 = myNameAndAge9_6(oilaName: "M_Kaku堂", oilaAge: 43)
print("oilaNameAge9_6:\(oilaNameAge9_6)")
oilaNameAge9_6 = "誰かさん達、きりきりまい"
print(oilaNameAge9_6)

8 初期値を設定も出来る

//初期値を設定
func myNameAndAge9_7(oilaName myName:String = "M_Kaku堂",oilaAge myAge:Int = 43) ->String{
    var lowerName = myName.lowercased()
    return("オイラの名前は、\(lowerName)で歳は、\(myAge)歳")
}
//変数名にセット
var oilaNameAge9_7 = myNameAndAge9_7()
print("oilaNameAge9_7:\(oilaNameAge9_7)")
oilaNameAge9_7 = "とある事情で1月末まで、長い年末年始休暇"
print(oilaNameAge9_7)
てな感じ👀

9 関数の一部だけ操作

//関数の一部だけ操作
func myNameAndAge9_8(_ myName:String = "M_Kaku堂",myAge:Int = 43) ->String{
    return("オイラの名前は、\(myName)で歳は、\(myAge)歳")
}
//変数名にセット
var oilaAge9_8 = myNameAndAge9_8(myAge:27)
print("oilaAge9_8:\(oilaAge9_8)")

※ 型推論は使えない

//型を省略=型推論は使えない
func myNameAndAge9_9(myName = "M_Kaku堂",myAge = 43) ->String{
    return("オイラの名前は、\(myName)で歳は、\(myAge)歳")
}
//変数名にセット
var oilaAge9_9 = myNameAndAge9_9(myAge:27)
print("oilaAge9_9:\(oilaAge9_9)")

てな感じで、パラメータの型を省略すると、、、

てな感じでエラー

10 複数のパラメータ

//複合計算
func timeMesure9_10(_ milliSeconds: Double) -> (seconds: Double,minutes: Double,hours: Double, days: Double){
    let seconds = milliSeconds * 1000
    let minutes = seconds * 60
    let hours = seconds * 60 * 60
    let days = seconds * 60 * 60 * 24
    
    return(seconds,minutes,hours,days)
}
for cnt9_10 in 1...10 {
    var time9_10 = timeMesure9_10(Double(cnt9_10))
    print("\(cnt9_10)秒は、\(time9_10.seconds)ms")
    print("\(cnt9_10)分は、\(time9_10.minutes)ms")
    print("\(cnt9_10)時間は、\(time9_10.hours)ms")
    print("\(cnt9_10)日は、\(time9_10.days)ms")
}

てな感じで、関数の中で複数の値を計算させて、実行すると、、、

みたいなこともできる👀

11 可変パラメータ 範囲

func callPhoneNumber9_11(_ phoneNumbers:String...)
{
    for phoneNumber in phoneNumbers {
        print("登録電話番号は、上から順に、\(phoneNumber)です。")
    }
}

callPhoneNumber9_11(
    "03-XXXX-XXX1",
    "03-XXXX-XXX2",
    "03-XXXX-XXX3",
    "03-XXXX-XXX4"
)

みたいに、戻り値をアローで指定せずに、パラメータ自体に範囲をつけると、

てな感じで、複数の値を処理できる

12 可変パラメータ 変数

縦:横=1:3の長方形の面積をメートルからセンチメートルに直したいとして、、、

//面積計算
func calcSquareCM9_12(vertical:Double, horizontal:Double) -> Double{
    var vertical = vertical
    var horizontal = horizontal
    let meter: Double = 100
    vertical = vertical * meter
    horizontal = horizontal * meter
 
    return vertical * horizontal
}

for cnt9_12 in 1...10 {
    print("縦が\(cnt9_12)メートルの面積は、\(calcSquareCM9_12(vertical: Double(cnt9_12), horizontal: Double(cnt9_12 * 3)))センチメートル")
}

みたいな感じで、実行すると

てな感じ

なんだけど、実はパラメータの値を変数に置き換えてるところをコメントアウトすると、、、

てな感じで、エラー警告が出るから、

これだけでも、

パラメータ=定数:let

ってことがわかるよね👀

13 inout

//入出力
func multipleNumber9_13(_ number: Int) -> Int{
    var number = number
    number *= number
    return(number)
}
var myNumber9_13 = 123
print("関数実行前:\(myNumber9_13)")
print("関数実行:\(multipleNumber9_13(myNumber9_13))")
print("関数実行後:\(myNumber9_13)")

てな感じのコードで、実行すると、

てな感じなんだけど
//入出力
func multipleNumber9_13(_ number: inout Int) -> Int{
//    var number = number
    number *= number
    return(number)
}
var myNumber9_13 = 123
print("関数実行前:\(myNumber9_13)")
print("関数実行:\(multipleNumber9_13( &myNumber9_13))")
print("関数実行後:\(myNumber9_13)")

てな感じで

inoutをパタメータの型につけて、&で値を呼び出すと、、、

実行後は、関数を通過した値になったね👀
値渡しか参照渡しみたいなもんだね

14 パラメータとして関数を利用

//パラメータとして関数を使う
//メートルをセンチメートルに変換
func meterToCm9_14(length: Double) -> Double{
    return length * 100
}
//メートルをキロメートルに変換
func meterToKm9_14(length: Double) -> Double{
    return length / 1000
}
//メートルをセンチメートルに変換メッセージ
func outputChangedCm(_ changeFunc: (Double) -> Double, value: Double){
    let changeResult = changeFunc(value)
    print("変更結果は、\(changeResult)センチです")
}
//メートルをキロメートルに変換メッセージ
func outputChangedKm(_ changeFunc: (Double) -> Double, value: Double){
    let changeResult = changeFunc(value)
    print("変更結果は、\(changeResult)キロメートルです")
}
//関数をパラメータとして定義
let cmLength = meterToCm9_14
let kmLength = meterToKm9_14
//値を指定例①
outputChangedCm(cmLength, value: 10)
outputChangedKm(kmLength, value: 20)
//値を指定例②
for cnt9_14 in 1 ... 1000 {
    var meterValue = Double(cnt9_14)
    outputChangedCm(cmLength, value: meterValue)
    outputChangedKm(kmLength, value: meterValue)
}

てな感じのコードを実行すると、、、👀

てな感じなる

っと、

if文なんかを噛ませた関数も例示しようかなあと思ったんだけど、今回は時間が来てしまったのと、これ以上やると複雑になりそうって思ったのでこの辺で。。。

まとめ

関数って他のプログラミング言語同様に、
単に関数を定義して呼び出すが基本なんだけど、

呼び出し方、利用の仕方、inout、パラメータ化などなど、結構、色々なことができる

ってイメージが付けば十分🕺

あとは自分で叩いて動かしてみて、慣れるだけ〜〜〜

今回のサンプルコード(まだ章の途中だけど、、、💦)

/**:---------------------------------------------------------
  Essentials 第9章
 -----------------------------------------------------------*/
//基本
//オイラの名前関数を宣言
func myName9_1(){
    print("M_Kaku堂")
}
//関数を呼び出して実行
myName9_1()

//名前と年齢関数
func myNameAndAge9_2(myName:String,myAge:Int) ->String{
    return("オイラの名前は、\(myName)で歳は、\(myAge)歳")
}
print(myNameAndAge9_2(myName: "M_Kaku堂", myAge: 43))

//名前と年齢関数の名前を小文字に〜〜
func myNameAndAge9_3(myName:String,myAge:Int) ->String{
    let lowerName9_3 = myName.lowercased()
    return("オイラの名前は、\(lowerName9_3)で歳は、\(myAge)歳")
}
print(myNameAndAge9_3(myName: "M_Kaku堂", myAge: 43))

//変数の値として呼び出し〜〜〜
func myNameAndAge9_4(myName:String,myAge:Int) ->String{
    let lowerName9_4 = myName.lowercased()
    return("オイラの名前は、\(lowerName9_4)で歳は、\(myAge)歳")
}
//変数名にセット
var oilaNameAge9_4 = myNameAndAge9_4(myName: "M_Kaku堂", myAge: 43)
print("oilaNameAge9_4:\(oilaNameAge9_4)")
oilaNameAge9_4 = "岸田さんてんてこまい"
print(oilaNameAge9_4)

//パラメータ名を省略〜〜〜
func myNameAndAge9_5(_ myName:String,_ myAge:Int) ->String{
    var lowerName = myName.lowercased()
    return("オイラの名前は、\(lowerName)で歳は、\(myAge)歳")
}
//変数名にセット
var oilaNameAge9_5 = myNameAndAge9_5("M_Kaku堂", 43)
print("oilaNameAge9_5:\(oilaNameAge9_5)")
oilaNameAge9_5 = "松野さん寿司ざんまい"
print(oilaNameAge9_5)

//キーワード〜〜〜
func myNameAndAge9_6(oilaName myName:String,oilaAge myAge:Int) ->String{
    var lowerName = myName.lowercased()
    return("オイラの名前は、\(lowerName)で歳は、\(myAge)歳")
}
//変数名にセット
var oilaNameAge9_6 = myNameAndAge9_6(oilaName: "M_Kaku堂", oilaAge: 43)
print("oilaNameAge9_6:\(oilaNameAge9_6)")
oilaNameAge9_6 = "誰かさん達、きりきりまい"
print(oilaNameAge9_6)

//初期値を設定
func myNameAndAge9_7(oilaName myName:String = "M_Kaku堂",oilaAge myAge:Int = 43) ->String{
    var lowerName = myName.lowercased()
    return("オイラの名前は、\(lowerName)で歳は、\(myAge)歳")
}
//変数名にセット
var oilaNameAge9_7 = myNameAndAge9_7()
print("oilaNameAge9_7:\(oilaNameAge9_7)")
oilaNameAge9_7 = "とある事情で1月末まで、長い年末年始休暇"
print(oilaNameAge9_7)

//関数の一部だけ操作
func myNameAndAge9_8(_ myName:String = "M_Kaku堂",myAge:Int = 43) ->String{
    return("オイラの名前は、\(myName)で歳は、\(myAge)歳")
}
//変数名にセット
var oilaAge9_8 = myNameAndAge9_8(myAge:27)
print("oilaAge9_8:\(oilaAge9_8)")

/**
 //型を省略=型推論→エラー
 func myNameAndAge9_9(myName = "M_Kaku堂",myAge = 43) ->String{
     return("オイラの名前は、\(myName)で歳は、\(myAge)歳")
 }
 //変数名にセット
 var oilaAge9_9 = myNameAndAge9_9(myAge:27)
 print("oilaAge9_9:\(oilaAge9_9)")
 */

//複合計算
func timeMesure9_10(_ milliSeconds: Double) -> (seconds: Double,minutes: Double,hours: Double, days: Double){
    let seconds = milliSeconds * 1000
    let minutes = seconds * 60
    let hours = seconds * 60 * 60
    let days = seconds * 60 * 60 * 24
    
    return(seconds,minutes,hours,days)
}
for cnt9_10 in 1...10 {
    var time9_10 = timeMesure9_10(Double(cnt9_10))
    print("\(cnt9_10)秒は、\(time9_10.seconds)ms")
    print("\(cnt9_10)分は、\(time9_10.minutes)ms")
    print("\(cnt9_10)時間は、\(time9_10.hours)ms")
    print("\(cnt9_10)日は、\(time9_10.days)ms")
}

//可変パラメータ
func callPhoneNumber9_11(_ phoneNumbers:String...)
{
    for phoneNumber in phoneNumbers {
        print("登録電話番号は、上から順に、\(phoneNumber)です。")
    }
}

callPhoneNumber9_11(
    "03-XXXX-XXX1",
    "03-XXXX-XXX2",
    "03-XXXX-XXX3",
    "03-XXXX-XXX4"
)

//面積計算
func calcSquareCM9_12(vertical:Double, horizontal:Double) -> Double{
    var vertical = vertical
    var horizontal = horizontal
    let meter: Double = 100
    vertical = vertical * meter
    horizontal = horizontal * meter
 
    return vertical * horizontal
}

for cnt9_12 in 1...10 {
    print("縦が\(cnt9_12)メートルの面積は、\(calcSquareCM9_12(vertical: Double(cnt9_12), horizontal: Double(cnt9_12 * 3)))センチメートル")
}

//入出力
func multipleNumber9_13(_ number: inout Int) -> Int{
//    var number = number
    number *= number
    return(number)
}
var myNumber9_13 = 123
print("関数実行前:\(myNumber9_13)")
print("関数実行:\(multipleNumber9_13( &myNumber9_13))")
print("関数実行後:\(myNumber9_13)")

//パラメータとして関数を使う
//メートルをセンチメートルに変換
func meterToCm9_14(length: Double) -> Double{
    return length * 100
}
//メートルをキロメートルに変換
func meterToKm9_14(length: Double) -> Double{
    return length / 1000
}
//メートルをセンチメートルに変換メッセージ
func outputChangedCm(_ changeFunc: (Double) -> Double, value: Double){
    let changeResult = changeFunc(value)
    print("変更結果は、\(changeResult)センチです")
}
//メートルをキロメートルに変換メッセージ
func outputChangedKm(_ changeFunc: (Double) -> Double, value: Double){
    let changeResult = changeFunc(value)
    print("変更結果は、\(changeResult)キロメートルです")
}
//関数をパラメータとして定義
let cmLength = meterToCm9_14
let kmLength = meterToKm9_14
//値を指定例①
outputChangedCm(cmLength, value: 10)
outputChangedKm(kmLength, value: 20)
//値を指定例②
for cnt9_14 in 1 ... 1000 {
    var meterValue = Double(cnt9_14)
    outputChangedCm(cmLength, value: meterValue)
    outputChangedKm(kmLength, value: meterValue)
}

さてと、次回は

💃クロージャをやってく〜〜〜🕺

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