Rumah > Tutorial sistem > LINUX > Analisis mendalam tentang penggunaan fungsi Kotlin dan prinsip pengaturcaraan berfungsi

Analisis mendalam tentang penggunaan fungsi Kotlin dan prinsip pengaturcaraan berfungsi

WBOY
Lepaskan: 2023-12-29 14:27:19
ke hadapan
1400 orang telah melayarinya
Pengenalan Artikel ini terutamanya memperkenalkan penggunaan fungsi Kotlin dan beberapa pemahaman saya tentang pengaturcaraan berfungsi. Dan akan membuat beberapa perbandingan dengan Python dan C++.

Sejak bapa Google mengumumkan Kotlin sebagai anak baptisnya, Kotlin telah menjadi sangat popular di komuniti utama.
Jika anda tidak tahu apa-apa tentang sintaks Kotlin, anda disyorkan untuk membaca dokumentasi rasmi atau tapak web Cina (https://www.kotlincn.net/docs/reference/) sebelum membaca artikel ini untuk pemahaman yang lebih mendalam.

Berikut ialah definisi pengaturcaraan berfungsi daripada Wikipedia:

Pengaturcaraan fungsian (Bahasa Inggeris: pengaturcaraan berfungsi), juga dikenali sebagai pengaturcaraan fungsian, ialah paradigma pengaturcaraan yang menganggap operasi komputer sebagai pengiraan fungsi matematik dan mengelakkan penggunaan keadaan atur cara dan objek yang tidak menentu . Asas terpenting bahasa pengaturcaraan berfungsi ialah kalkulus lambda. Dan fungsi kalkulus lambda boleh menerima fungsi sebagai input (argumen) dan output (nilai keluar).

Berikut ialah takrifan fungsi tertib tinggi:

Dalam matematik dan sains komputer, fungsi tertib tinggi ialah fungsi yang memenuhi sekurang-kurangnya satu daripada syarat berikut: menerima satu atau lebih fungsi sebagai input dan mengeluarkan fungsi

Tidak sukar untuk membuat kesimpulan bahawa asas pengaturcaraan berfungsi yang paling penting ialah fungsi peringkat tinggi. Iaitu, fungsi sokongan boleh menerima fungsi sebagai input (argumen) dan output (nilai keluar).

Sebagai warga kelas pertama di Kotlin, fungsi boleh digunakan sebagai input dan output fungsi seperti objek lain. Inilah titik yang pengaturcara Java mendapati perubahan terbesar dan paling sukar difahami apabila mereka beralih kepada Kotlin. Jika anda pernah mempelajari Python atau C++11 sebelum ini, ini mungkin lebih mudah untuk anda. Inilah sebabnya mengapa artikel ini terutamanya memperkenalkan fungsi Kotlin dan pengaturcaraan berfungsi.

Fungsi Kotlin

Berikut ialah definisi fungsi umum dalam Kotlin Perbezaan dari Java ialah parameter fungsi diletakkan terakhir, dan jenis nilai pulangan diletakkan terakhir. Badan fungsi boleh diberikan kepada definisi fungsi menggunakan tanda sama, dan kesamaan fungsi dan pembolehubah juga boleh dilihat di sini.

fun main(args: Array) {
    var s = sum(1,2)
    var m = multi(2,3)
    var x = maxOf(3,4)
}

fun sum(a: Int, b: Int): Int {
    return a + b
}

fun multi(a: Int, b: Int): Int = a * b

fun maxOf(a: Int, b: Int): Int = if (a > b) a else b
Salin selepas log masuk

Selain itu, Kotlin juga menyokong parameter lalai fungsi, fungsi lanjutan dan ungkapan infix Berikut ialah contoh mudah:

fun main(args: Array) {
    isBiggerThan(2)
    isBiggerThan(2, 5)
    var s = "a".isLetter()
    var a = 1 add 2
}

fun isBiggerThan(a: Int, b: Int = 0) {
    return a > b
}

//拓展函数
fun String.isLetter(): Boolean {
    return matches(Regex("^[a-z|A-Z]$"))
}

//拓展函数,中缀表达式
infix fun Int.add(x: Int): Int {
    return this + x
}
Salin selepas log masuk

Fungsi yang menyokong parameter lalai boleh mengurangkan lebihan beban fungsi.

Tiada kaedah dalam objek String untuk menentukan sama ada ia adalah huruf Dalam Java, kami biasanya mentakrifkan beberapa kaedah Utils, manakala dalam Kotlin, kami boleh menentukan fungsi sambungan kelas.
Contoh kedua ialah untuk mentakrifkan fungsi sambungan untuk kelas Int, dan fungsi sambungan dinyatakan sebagai ungkapan infix, memberikan hak kepada pembangun untuk menentukan kata kunci yang serupa.

Sebagai contoh, kita boleh mencipta objek peta seperti ini:

val kv = mapOf("a" to 1, "b" to 2)
Salin selepas log masuk

Di sini adalah ungkapan infiks, ditakrifkan seperti berikut:

public infix fun<A, B> A.to(that: B): Pair<A, B> = Pair(this, that)
Salin selepas log masuk

Pair ialah objek yang disimpan dalam Peta, jadi anda juga boleh menciptanya seperti ini

val kv = mapOf(Pair("a", 1), Pair("b", 2))
Salin selepas log masuk

Dalam Python, jika kita mahu fungsi itu mengembalikan berbilang nilai, kita boleh mengembalikan tuple Kotlin juga boleh mencapai fungsi yang serupa berdasarkan prinsip pemusnahan:

fun main(args: Array) {
    val (index, count) = findWhere("abcabcabcabc", 'c')
}

fun findWhere(str: String, findChar: Char): Pair<Int, Int> {
    var index = -1
    var count = 0
    for ((i, v) in str.withIndex()) {
        if (v == findChar) {
            if (index == -1) {
                index = i
            }
            ++count
        }
    }
    return Pair(index, count)
}
Salin selepas log masuk

Sila semak dokumentasi rasmi untuk mengetahui cara objek tersuai menyokong pemusnahan, supaya ia boleh dilalui seperti berikut:

for ((k, v) in map) {
    print("$k -> $v, ")
}
Salin selepas log masuk
Fungsi tertib lebih tinggi dan ekspresi Lambda

"Ekspresi lambda" (ungkapan lambda) ialah fungsi tanpa nama yang dinamakan berdasarkan kalkulus lambda dalam matematik Ia sepadan secara langsung dengan abstraksi lambda (abstraksi lambda, iaitu fungsi tanpa nama). nama fungsi. Ungkapan Lambda boleh mewakili penutupan (perhatikan bahawa ia berbeza daripada pengertian matematik tradisional).

Ekspresi Lambda dalam Python:

add = lambda x, y:x+y
Salin selepas log masuk

lambda dalam C++:

[](int x, int y) -> int{ return x + y; }
Salin selepas log masuk

lambda dalam Kotlin:

var add = {x: Int, y: Int -> x + y}
Salin selepas log masuk

Kotlin agak mudah sebagai bahasa yang ditaip dengan kuat.

Kita boleh menggunakan ungkapan lambda seperti ini:

fun main(args: Array) {
val sumLambda = {a: Int, b: Int -> a + b}
sumLambda(1, 2)
}
Salin selepas log masuk

Ia boleh dipanggil menggunakan () seperti fungsi Dalam kotlin, operator boleh terlebih beban Operator () sepadan dengan invoke() fungsi yang terlebih beban.

Anda juga boleh mentakrifkan pembolehubah seperti ini:

val numFun: (a: Int, b: Int) -> Int
Salin selepas log masuk

Ia bukan pembolehubah biasa, ia mesti menunjuk kepada fungsi, dan tandatangan fungsi mestilah konsisten:

fun main(args: Array) {
    val sumLambda = {a: Int, b: Int -> a + b}
    var numFun: (a: Int, b: Int) -> Int
    numFun = {a: Int, b: Int -> a + b}
    numFun = sumLambda
    numFun = ::sum
    numFun(1,2)
}

fun sum(a: Int, b: Int): Int {
    return a + b
}
Salin selepas log masuk

Anda boleh melihat bahawa pembolehubah ini boleh sama dengan ungkapan lambda, pembolehubah ungkapan lambda lain atau fungsi biasa, tetapi anda perlu menambah (::) sebelum nama fungsi untuk mendapatkan rujukan fungsi.

Ini adalah serupa dengan penuding fungsi dalam C++ Namun, dalam Python anda boleh terus menggunakan nama fungsi sebagai rujukan fungsi Berikut ialah contoh penunjuk fungsi C++:

#include 

using namespace std;

void swap(int &x, int &y);

int main(int arg, char* args[]) {
	int x = 10;
	int y = 20;

	void (*methodPtr)(int &x, int &y);//声明一个函数指针
	methodPtr = &swap; //函数指针赋值
	methodPtr = swap;//取地址符可省略,效果和上面一致
	methodPtr(x, y); //像给函数起了一个别名,可以直接使用()调用
	cout << "x:" << x << " y:" << y << endl; //x:20 y:10
}

void swap(int &x, int &y) {
	int tmp = x;
	x = y;
	y = tmp;
}
Salin selepas log masuk

Kembali ke Kotlin, kita juga boleh menghantar satu fungsi ke fungsi lain, seperti:

//函数参数
fun  doMap(list: List, function: (it: T) -> Any) {
    for (item in list) {
        function(item)
    }
}
Salin selepas log masuk

Parameter pertama ialah Senarai, dan parameter kedua ialah fungsi Tujuannya adalah untuk melaksanakan fungsi kedua sekali untuk setiap elemen dalam Senarai. Cara penggunaan:

val strList = listOf("h" ,"e", "1", "a", "b", "2", " ", "", "c", "5", "7", "F")
doMap(strList, {item ->print("item: ${upperLetter(item)}, ") })

fun upperLetter(item: String): String {
    if (item.isLetter()) {
        return item.toUpperCase()
    }
    return item
}
Salin selepas log masuk

Parameter kedua dihantar terus ke dalam ungkapan lambda Sudah tentu, rujukan fungsi juga boleh dihantar dalam:

val strList = listOf("h" ,"e", "1", "a", "b", "2", " ", "", "c", "5", "7", "F")
doMap(strList, ::printUpperLetter)

fun printUpperLetter(item: String) {
    print("item: ${upperLetter(item)}, ")
}

fun upperLetter(item: String): String {
    if (item.isLetter()) {
        return item.toUpperCase()
    }
    return item
}
Salin selepas log masuk

Kesannya sama seperti kod di atas.

Kesan yang serupa boleh dicapai menggunakan penunjuk fungsi dalam C++:

using namespace std;

void mMap(vector list, void (*fun)(int item));

int main(int arg, char* args[]) {
	vector list = {2,3,4,3,2,1,2};
	mMap(list, [](int item) -> void { cout << item << endl; });
}

void mMap(vector list, void (*fun)(int item)) {
	for(int it : list) {
	    fun(it);
	}
}
Salin selepas log masuk

Kembali ke Kotlin sekali lagi, jika fungsi tersebut adalah yang terakhir dalam senarai parameter sebagai parameter input, anda juga boleh melakukan ini dan menulisnya terus dalam kurungan kerinting:

fun main(args: Array) {
    log { sum(1,2) }
}

fun  log(function: () -> T) {
    val result = function()
    println("result -> $result")
}
Salin selepas log masuk

Bukankah ini sedikit seperti cara fail konfigurasi gradle ditulis, jadi Kotlin boleh menulis bahasa khusus domain (DSL) dengan mudah

Selain itu, Kotlin juga menyokong fungsi dan fungsi setempat sebagai nilai pulangan, lihat kod berikut:

fun main(args: Array) {
    val addResult = lateAdd(2, 4)
    addResult()
}
//局部函数,函数引用
fun lateAdd(a: Int, b: Int): Function0 {
    fun add(): Int {
        return a + b
    }
    return ::add
}
Salin selepas log masuk

在lateAdd内部定义了一个局部函数,最后返回了该局部函数的引用,对结果使用()操作符拿到最终的结果,达到延迟计算的目的。

函数作为一级公民当然可以像普通对象一样放进map中,比如下面这样:

val funs = mapOf("sum" to ::sum)
val mapFun = funs["sum"]
if (mapFun != null) {
   val result = mapFun(1,2)
   println("sum result -> $result")
}

fun sum(a: Int, b: Int): Int {
    return a + b
}
Salin selepas log masuk

将一个函数引用作为value放进了map中,取出来之后使用()操作符调用,可以简化一些if,else的场景。

基于以上函数式编程的特性,Kotlin可以像RxJava一样很方便的进行相应式编程,比如:

fun printUpperLetter(list: List) {
    list
            .filter (fun(item):Boolean {
                return item.isNotEmpty()
            })
            .filter { item -> item.isNotBlank()}
            .filter {
                item ->
                if (item.isNullOrEmpty()) {
                    return@filter false
                }
                return@filter item.matches(Regex("^[a-z|A-Z]$"))
            }
            .filter { it.isLetter() }
            .map(String::toUpperCase)
            .sortedBy { it }
            .forEach { print("$it, ") }
    println()
}
Salin selepas log masuk

上面的代码只是做演示,并无实际意义。具体语法请查看官方文档。

我相信Kotlin作为一种强类型的现代化语言可以在保证稳定性的同时极大地提高开发者的开发效率。

Atas ialah kandungan terperinci Analisis mendalam tentang penggunaan fungsi Kotlin dan prinsip pengaturcaraan berfungsi. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:linuxprobe.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan