함수 선언
코틀린의 함수는 fun 키워드를 사용하여 선언됩니다 .
fun double(x: Int): Int {
return 2*x
}
함수 사용법
함수 호출은 전통적인 방식을 사용합니다.
val result = double(2)
멤버 함수를 호출하면 점 표기법이 사용됩니다.
Sample().foo() // Sample 클래스의 인스턴스를 생성하고 foo호출
파라미터
함수 매개 변수는 파스칼 표기법, 즉 name : type을 사용하여 정의됩니다 . 매개 변수는 쉼표로 구분됩니다. 각 매개 변수는 명시 적으로 입력해야합니다.
fun powerOf(number: Int, exponent: Int) {
...
}
기본 인수
함수 매개 변수는 기본값을 가질 수 있으며 해당 인수가 생략 될 때 사용됩니다. 이렇게하면 다른 언어에 비해 과부하가 줄어 듭니다.
fun read(b: Array<Byte>, off: Int = 0, len: Int = b.size) {
...
}
기본값은 값 과 함께 = after 유형을 사용하여 정의됩니다 .
대체 메소드는 항상 기본 메소드와 동일한 기본 매개 변수 값을 사용합니다. 기본 매개 변수 값을 사용하여 메서드를 재정의하는 경우 서명에서 기본 매개 변수 값을 생략해야합니다.
open class A {
open fun foo(i: Int = 10) { ... }
}
class B : A() {
override fun foo(i: Int) { ... } // no default value allowed
}
기본 매개 변수가 기본값이없는 매개 변수 앞에 오는 경우 명명 된 인수로 함수를 호출해야 기본값을 사용할 수 있습니다 .
fun foo(bar: Int = 0, baz: Int) { /* ... */ }
foo(baz = 1) // The default value bar = 0 is used
그러나 마지막 인수 lambda 가 괄호 밖의 함수 호출에 전달되면 기본 매개 변수에 값을 전달하지 않을 수 있습니다.
fun foo(bar: Int = 0, baz: Int = 1, qux: () -> Unit) { /* ... */ }
foo(1) { println("hello") } // Uses the default value baz = 1
foo { println("hello") } // Uses both default values bar = 0 and baz = 1
이름 인수
함수 매개 변수는 함수를 호출 할 때 명명 될 수 있습니다. 이것은 함수가 많은 수의 매개 변수 또는 기본 매개 변수를 가질 때 매우 편리합니다.
주어진 다음 함수 :
fun reformat(str: String,
normalizeCase: Boolean = true,
upperCaseFirstLetter: Boolean = true,
divideByCamelHumps: Boolean = false,
wordSeparator: Char = ' ') {
...
}
기본 인수를 사용하여 이것을 호출 할 수 있습니다.
reformat(str)
그러나 기본값이 아닌 호출을 사용하면 다음과 같이 호출됩니다.
reformat(str, true, true, false, '_')
이름 인수를 사용하면 코드를 훨씬 쉽게 읽을 수 있습니다.
reformat(str,
normalizeCase = true,
upperCaseFirstLetter = true,
divideByCamelHumps = false,
wordSeparator = '_'
)
우리가 모든 주장을 필요로하지 않는다면 :
reformat(str, wordSeparator = '_')
함수가 위치 인수와 이름 인수를 모두 사용하여 호출되면, 모든 위치 인수는 첫 번째 인수 인수 앞에 놓여 야합니다. 예를 들어 호출 f(1, y = 2)
은 허용되지만 f(x = 1, 2)
그렇지 않습니다.
가변 개수의 인수 ( vararg ) 는 스프레드 연산자 를 사용하여 명명 된 형식으로 전달할 수 있습니다 .
fun foo(vararg strings: String) { /* ... */ }
foo(strings = *arrayOf("a", "b", "c"))
foo(strings = "a") // Not required for a single value
Java 바이트 코드는 항상 함수 매개 변수의 이름을 유지하지 않기 때문에 Java 함수 호출시 명명 된 인수 구문을 사용할 수 없습니다.
단위 반환 함수
함수가 유용한 값을 리턴하지 않으면 그 리턴 유형은 다음과 같습니다 Unit
. Unit
값이 하나 뿐인 유형입니다 Unit
. 이 값을 명시 적으로 반환 할 필요는 없습니다.
fun printHello(name: String?): Unit {
if (name != null)
println("Hello $")
else
println("Hi there!")
// `return Unit` 또는 `return` 생략 기능
}
Unit
반환 형식 선언은 선택 사항입니다. 위의 코드는 다음과 같습니다.
fun printHello(name: String?) {
...
}
단일 표현식 함수
함수가 단일 표현식을 반환하면 중괄호를 생략하고 a = 기호 다음에 본문을 지정합니다 .
fun double(x: Int): Int = x * 2
명시 적으로 반환 형식을 선언하는 것은 컴파일러에서이를 유추 할 수있는 경우 선택 사항입니다 .
fun double(x: Int) = x * 2
리턴 타입 지정
그들에게 반환하는 것이이 의도하지 않는 블록 몸의 기능은 항상 명시 적으로 반환 형식을 지정해야합니다 Unit
, 이 경우는 선택 사항입니다 . Kotlin은 블록 본문이있는 함수의 반환 형식을 유추하지 않습니다. 이러한 함수는 본문에서 복잡한 제어 흐름을 가질 수 있으며 반환 형식은 독자 (그리고 때로는 컴파일러의 경우조차도)에게 명백하지 않기 때문입니다.
가변 인수 (Varargs)
함수의 매개 변수 (일반적으로 마지막 매개 변수)는 vararg
수정 자로 표시 될 수 있습니다 .
fun <T> asList(vararg ts: T): List<T> {
val result = ArrayList<T>()
for (t in ts) // ts is an Array
result.add(t)
return result
}
다양한 수의 인수를 함수에 전달할 수 있습니다.
val list = asList(1, 2, 3)
함수 내에서 vararg
타입 의 -parameter T
는 배열로 볼 수 있습니다 T
. 즉, ts
위 예의 변수는 타입을가 Array<out T>
집니다.
하나의 매개 변수만으로 표시 될 수 있습니다 vararg
. 경우 vararg
파라미터는 상기 목록의 마지막 아니다 파라미터 람다를 외부 호를 전달하여, 기능 타입을 갖는 경우, 다음과 같은 매개 변수의 값은 지정된 인자 구문을 사용하여 전달하거나 할 수있다.
우리가 vararg
-function 을 호출 할 때 , 우리는 인수를 하나씩 전달할 수 있습니다. 예를 들어 asList(1, 2, 3)
배열이 이미 있고 그 내용을 함수에 전달하고자한다면, spread 연산자를 사용합니다 *
:
val a = arrayOf(1, 2, 3)
val list = asList(-1, 0, *a, 4)
중위 어 표기법
함수는 중첩 표기법을 사용하여 호출 할 수 있습니다.
- 멤버 함수 또는 확장 함수입니다 .
- 단일 매개 변수가 있습니다.
- 그들은
infix
키워드 로 표시됩니다 .
// Define extension to Int
infix fun Int.shl(x: Int): Int {
...
}
// call extension function using infix notation
1 shl 2
// is the same as
1.shl(2)
함수 범위
Kotlin 함수에서는 파일의 최상위 레벨에서 함수를 선언 할 수 있습니다. 즉, Java, C # 또는 Scala와 같은 언어와 같은 함수를 보유 할 클래스를 만들 필요가 없습니다. 최상위 함수 외에도 Kotlin 함수는 멤버 함수 및 확장 함수로 로컬로 선언 될 수도 있습니다.
로컬 함수
Kotlin은 지역 함수, 즉 다른 함수 내부의 함수를 지원합니다.
fun dfs(graph: Graph) {
fun dfs(current: Vertex, visited: Set<Vertex>) {
if (!visited.add(current)) return
for (v in current.neighbors)
dfs(v, visited)
}
dfs(graph.vertices[0], HashSet())
}
로컬 함수는 외부 함수의 로컬 변수 (즉, 클로저)에 액세스 할 수 있으므로 위의 경우 방문한 변수는 로컬 변수가 될 수 있습니다.
fun dfs(graph: Graph) {
val visited = HashSet<Vertex>()
fun dfs(current: Vertex) {
if (!visited.add(current)) return
for (v in current.neighbors)
dfs(v)
}
dfs(graph.vertices[0])
}
멤버 함수
멤버 함수는 클래스 나 객체 내부에 정의 된 함수입니다.
class Sample() {
fun foo() { print("Foo") }
}
멤버 함수는 점 표기법으로 호출됩니다.
Sample().foo() // Sample 클래스의 인스턴스를 생성하고 foo 호출
클래스 및 재정의 멤버에 대한 자세한 내용은 클래스 및 상속을 참조하십시오 .
지네릭 함수
함수는 함수 이름 앞에 꺾쇠 괄호를 사용하여 지정되는 일반 매개 변수를 가질 수 있습니다.
fun <T> singletonList(item: T): List<T> {
// ...
}
일반 함수에 대한 자세한 내용은 Generics를 참조하십시오 .
인라인 함수
확장 기능
고차 함수와 람다
Higher-Order 함수와 Lambda는 자체 섹션 에서 설명 합니다 .
꼬리 재귀 함수
Kotlin은 꼬리 재귀 라고하는 함수 프로그래밍 스타일을 지원합니다 . 이렇게하면 일반적으로 루프를 사용하여 쓰여지는 일부 알고리즘 대신 재귀 함수를 사용하여 쓰지만 스택 오버플로의 위험은 없습니다. 함수가 tailrec
수정 자로 표시되고 필수 형식을 충족하면 컴파일러는 재귀를 최적화하여 대신 빠르고 효율적으로 루프 기반 버전을 남깁니다.
tailrec fun findFixPoint(x: Double = 1.0): Double
= if (x == Math.cos(x)) x else findFixPoint(Math.cos(x))
이 코드는 수학 상수 인 코사인 고정 점을 계산합니다. 결과가 더 이상 변하지 않을 때까지 1.0에서 반복 시작되는 Math.cos를 반복적으로 호출하여 결과는 0.7390851332151607입니다. 결과 코드는보다 전통적인 스타일과 동일합니다.
private fun findFixPoint(): Double {
var x = 1.0
while (true) {
val y = Math.cos(x)
if (x == y) return y
x = y
}
}
tailrec
수정자를 적합하게하려면 함수가 수행하는 마지막 작업으로 함수를 호출해야합니다. 재귀 호출 후에 더 많은 코드가있을 때 꼬리 재귀를 사용할 수 없으며 try / catch / finally 블록 내에서 사용할 수 없습니다. 현재 꼬리 재귀는 JVM 백엔드에서만 지원됩니다.
'프로그래밍 > kotlin' 카테고리의 다른 글
코틀린 - 데이터 클래스 (0) | 2021.04.25 |
---|---|
코틀린 - 확장 (0) | 2021.04.25 |
코틀린 - 고차 함수와 람다 (0) | 2021.04.18 |
코틀린 - 인라인 함수 (0) | 2021.04.18 |
코틀린 - 코루틴 (0) | 2021.04.18 |