[TIL]関数と関数式プログラミング


Do it! コートリンプログラミングを学ぶ

✏️1. 関数とは?✏️

  • は、機能を実行するために複数の値を受け入れる、欠落した値のコードのセット
  • を返す.
    なぜ
  • 関数を使用しますか?
  • 再利用可能コード
    勘定科目の構造
    fun 함수 이름([변수 이름: 자료형]): [반환값의 자료형] {
    	표현식 ...
    	[return 반환값]
    } // 대괄호([]) 안의 내용은 생략 가능

    1-1. 関数呼び出しとメモリ

  • プログラム実行後メモリにプログラムのためのスペース
  • を作成する.
  • 関数の各情報をフレーム(Frame)と呼ぶ情報はスタックメモリの高アドレスから充填され、
  • が逆の順序で破棄する.
    勘定科目の勘定科目関数呼び出しの原理
    fun main(){
    	val num1 = 10
        val num2 = 3
        val result: Int
        
        result = max(num1, num2)
        println(result)
    }
    
    fun max(a:Int, b:Int) = if (a>b) a else b

    1-2. 戻り値のない関数とパラメータ


    📌 戻り値のない関数
  • 関数に戻り値がない場合は、関数のデータ型を省略したり、Unitとして指定したりすることができます.
  • デバイスは、特殊オブジェクト(voidは何も返さない)
  • を返す.
    fun printSum(a: Int, b:Int): Unit { } // (1)
    fun printSum(a: Int, b:Int) { } // (2) Unit 생략
    ->(2)戻り値のデータ型は省略するが、実際に戻り値のデータ型はUnit
    📌 可変パラメータ
  • 関数は1つしか定義できず、複数のパラメータ
  • を受け入れることができる.
  • キーワード
  • を使用
    fun main(){
    	normalVarargs(1, 2, 3, 4)
        normalVarargs(4, 5, 6)
    }
    
    fun normalVarargs(vararg counts: Int){ // counts는 Int형의 배열이 됨
    	for (num in counts){
        	print("$num ")
        }
        print("\n")
    }

    ✏️2. 関数式プログラミング▼▼▼

  • コトリンは関数式プログラミングとオブジェクト向けプログラミングをサポートするマルチモデル言語
  • 関数式、オブジェクト向けプログラミング簡略化可能コード
  • 関数式プログラミングの利点
  • コード簡略化
  • のテストまたは再利用率の向上に伴い、開発作業効率は
  • 向上した.

    2-1. 関数プログラミングとは?


    ram多項式と高次関数をプログラミングテクニックとして用い,純粋な関数を記述することによってプログラムの副作用を低減する
    📌 純関数(Pure Function)
    副作用のない関数が関数外部のいかなる状態も変化しない場合、純関数と呼ぶ.
  • スレッドは安全で、テストコード
  • が容易である.
  • 純関数の条件
    パラメータ
  • については、常に同じ値
  • が返される.
  • 関数の外部の任意の状態を変更しない
  • 2-2. ランダ式と高次関数

  • 高次関数パラメータまたは戻り値として関数を使用する非常に柔軟な
  • ラム多式は、多くのコードを簡略化することができ、関数自体をパラメータまたはパラメータとし、プログラムの効率を向上させることができる
  • .
    📌 パラメータまたは戻り値として一般関数を使用する高次関数
    fun main(){
    	val res1 = sum(3,2)
    	val res2 = mul(sum(3,3), 3) // 인자에 함수 사용
    }
    
    fun sum(a: Int, b: Int) = a + b
    fun mul(a: Int, b: Int) = a * b
    📌 変数に割り当てられたram多項式関数
  • ramに割り当てられた変数は、関数のように
  • を使用することができる.
    fun main() {
    	var result: Int
        val multi = {x: Int, y:Int -> x * y } // 일반 변수에 람다식 할당
        result = multi(10,20) // 람다식이 할당된 변수는 함수처럼 사용 가능
        println(result)
    }
    📌 パラメータにラム多項式関数を用いた高次関数
    fun main() {
    	var result: Int
        result = highOrder({x, y -> x + y}, 10, 20) // 람다식을 매개변수와 인자로 사용
        println(result)
    }
    fun highOrder(sum: (Int, Int) -> Int, a: Int, b: Int): Int {
    	return sum(a, b)
    }
    📌 ラム多式資料型省略
    val multi: (Int, Int) -> Int = {x: Int, y: Int -> x * y}
    val multi = {x: Int, y: Int -> x * y}
    val multi: (Int, Int) -> Int = {x, y -> x * y}
    val multi = {x, y -> x * y} // !오류! 자료형 추론 불가
    📌 戻りタイプがない場合やパラメータが1つしかない場合のram式
    fun main() {
    	val greet: () -> Unit = { } // 인자와 반환값이 없는 람다식 함수
    	val square: (Int) -> Int = {x -> x * x} // 매개변수가 하나인 람다식 함수
    
    	greet() // 함수처럼 사용 가능
    }
    📌 ラムダ式パラメータ.
  • パラメータが1つしかない場合は、矢印を省略し、$itを使用して
  • を置き換えることができます.
    fun main() {
    	oneParam({ a -> "Hello World! $a"})
        oneParam {"Hello World! $it"}
    }
    
    fun oneParam(out: (String) -> string){
    	println(out("OneParam"))
    }

    2-3. ラムダ式と高次関数の呼び出し


    📌 値呼び出し
    関数が別の関数のパラメータとして伝達される場合、ラム多式関数は値として処理され、関数が直ちに実行された後に値が伝達されます.

    📌 名前によってラムティーを呼び出す
    名前がパラメータとして渡されるのではなく、実際の呼び出し時に実行されます.

    📌 参照による呼び出し(:)
    別の関数のパラメータから非ラム多項式の一般関数を呼び出すと、関数名に2つのコロン(:)が使用されます.
    パラメータと戻り値を持つ関数
    fun main() {
    	val res1 = funcParam(3, 2, ::sum) // 참조에 의한 호출
        println(res1)
        
        // 일반 변수에 값처럼 할당
        val likeLambda = ::sum
        println(likeLambda(3, 2))
    }
    
    fun sum(a: Int, b: Int) = a + b
    
    fun funcParam(a: Int, b: Int, c: (Int, Int) -> Int): Int {
    	return c(a, b)
    }
    パラメータのない関数
    fun main() {
    	hello(::text) // 반환값이 없음
        hello({a, b -> text(a, b)}) // 람다식 표현
        hello {a, b -> text(a, b)} //소괄호 생략
        // 위 3가지 표현은 모두 동일한 결과를 출력
    }
    fun text(a: String, b: String) = "Hi! $a $b"
    
    fun hello(body: (String, String) -> String): Unit {
    	println(body("Hello", "World"))
    }

    ✏️3. コトリンの各種関数▼▼


    3-1. 匿名関数

  • 名前のない一般的な関数
  • 関数本明細書の条件に従って関数を中断および戻す必要がある場合は、
  • を使用します.
    ¥匿名関数の例
    fun(x: Int, y: Int): Int = x + y
    
    val add: (Int, Int) -> Int = fun(x, y) = x + y // (1)
    val add = fun(x:Int, y:Int) = x + y // (2)
    val add = {x: Int, y: Int -> x + y} // (3)
    
    val result = add(10, 2)
    ->(1)のように、宣言資料型をラム多式に書き、変数addはラム多式関数のようにadd()とともに使用することができる
    ->(1)、(2)と(3)は同じ表現です

    3-2. 行内関数

  • 関数が呼び出された場所で関数本文のすべての内容
  • をコピーする
  • 関数のブランチなし処理により、コードの性能が向上する
  • 内容の短いカニ
  • 行内関数ram多項式パラメータを有する関数で動作
  • を実行する.
  • 行内関数の制限
  • 行内関数パラメータで使用するラムマルチコードが長すぎる場合や行内関数本文が長すぎる場合、コンパイラは性能警告
  • を発行することができる.
  • 行の関数を呼び出しすぎると、コード量が増加し、あまりよくない可能性があります.
  • ¥inline関数の例
    fun main() {
    	shortFunc(3) { println("First call: $it") }
        shortFunc(5) { println("First call: $it") }
    }
    
    inline fun shortFunc(a: Int, out: (Int) -> Unit) {
    	println("Before calling out()")
        out(a)
        println("After calling out()")
    }
    コードではshortFunc()関数が2回呼び出されたように見えます.
    fun main() {
    	// shortFunc(3) {  }
    	println("Before calling out()")
        println("First call: 3")
        println("After calling out()")
        
        // shortFunc(5) {  }
        println("Before calling out()")
        println("First call: 5")
        println("After calling out()")
    }
    逆コンパイルすると、shortFunc()関数の内容がコピーされます.(上のコードは逆コンパイルコードではなく、inline関数の動作を大まかに表しています)

    3-3. 拡張関数

  • コンセプトで、必要なターゲットにより多くの関数を追加できます.
  • 既存クラスの宣言の実装を変更することなく、
  • を外部から容易に拡張できます.
  • 同じ名前のメンバー関数またはメソッドが存在する場合、メンバーメソッドは常に拡張関数呼び出し
  • よりも優先される.
    拡張関数の定義
    fun 확장 대상.함수 이름(매개변수, ...): 반환값 {
    	...
        return}
    ¥Stringクラスに拡張関数を追加
    fun main() {
    	val source = "Hello World!"
        val target = "Kotlin"
        println(source.getLongString(target))
    }
    
    // String 클래스를 확장해 getLongString() 함수 추가
    fun String.getLongString(target: String): String = 
    	if(this.length > target.length) this else target

    3-4. 中央値(Infox Notation)

  • クラスメンバーを呼び出すときに使用されるポイント(.)表現法
  • は、省略して関数名の後に括弧を付けて直感的な名前を使用します.
  • 中位数関数の条件
  • メンバーメソッドまたは拡張関数は、
  • でなければなりません.
  • 個のパラメータ
  • が必要です
  • infixキーワード定義
  • を使用
    ¥2,000中尉表示法例
    fun main() {
    	// 일반 표현법
        val multi = 3.multiply(10)
        
        // 중위 표현법
        val multi = 3 multiply 10 
    }
    
    infix fun Int.multiply(x: Int): Int {
    	return this * x
    }

    3-5. 末尾再帰関数

  • テール再帰関数はスタックオーバーフロー現象
  • を解決することができる.
  • 再帰関数のように、スタックを続けるのではなく、
  • を繰り返します.
  • tairecキーワード
  • を使用

    ✏️4. 関数と変数の範囲


    4-1. 関数の範囲


    📌 最上位機能
    main()関数の前または後に宣言します.main()関数で関数を使用するには制約はありません.
    📌 ちいきかんすう
    関数に別の関数が宣言されている場合.
    勘定科目の最上位関数とリージョン関数
    fun a() = b() // 최상위 함수이므로 b() 함수 선언 위치에 상관없이 사용 가능
    fun b() = println("b")
    
    fun c() {
    	fun d() = e() // !오류! d()는 지역함수로 e()의 이름을 모름
        fun e() = println("e")
    }
    
    fun main() {
    	a() //최상위 함수는 어디서든 호출 가능
        e() // !오류! e()는 c의 블록 밖에서 사용 불가능
    }

    4-2. 変数の範囲


    📌 ゾーン変数
  • 特定コードブロックの変数
  • ブロックを離れると、プログラムメモリから
  • を削除する.
    📌 グローバル変数
    変数
  • は最上位にあります
  • プログラムの実行時に削除しないで、メモリの中で
  • を保留します
  • コードが長すぎる場合、グローバル変数のコードにアクセスすると、プログラムのエラー動作
  • が発生する.
  • 非アクティブグローバル変数によるメモリリソースの浪費