style guide
- 안드로이드 코틀린 스타일 가이드
- 들여쓰기 : “ “ x 4
- 변수명(camelCase), class/file(UpperCamel)
- 상수 : UPPER_SNAKE_CASE
- 대문자,
_로 단어 구분
- 대문자,
// const
const val NUMBER = 5
val NAMES = listOf("Alice", "Bob")
val AGES = mapOf("Alice" to 35, "Bob" to 32)
val COMMA_JOINER = Joiner.on(',') // Joiner is immutable
val EMPTY_ARRAY = arrayOf()
// varable
val variable = "var"
val nonConstScalar = "non-const"
val mutableCollection: MutableSet = HashSet()
val mutableElements = listOf(mutableInstance)
val mutableValues = mapOf("Alice" to mutableInstance, "Bob" to mutableInstance2)
val logger = Logger.getLogger(MyClass::class.java.name)
val nonEmptyArray = arrayOf("these", "can", "change")
공백
- 여는 중괄호(
{) 앞 - 예약어(예:
if,for또는catch)는 같은 줄에서 뒤에 오는 여는 괄호(()와 구분 - 2진 연산자의 양쪽
.,::,..: 붙여쓰기
// keyword
for (i in 0..1) {
}
} else {
}
// operand
val two = 1 + 1
// {}
if (list.isEmpty()) {
}
// , :
val oneAndTwo = listOf(1, 2)
class Foo : Runnable
// member
val toString = Any::toString
// method
it.toString()
// 범위 연산자
for (i in 1..4) {
print(i)
}
절차지향 및 함수형 언어
java의 객체지향 + 절차지향 + 함수형 추가
객체가 필수가 아님
- parameter, return값의 type 지정 필요
unit:void, 생략 가능
- 즉 return 값이 없다면
returnType생략 가능(혹은unit명시)
fun funName([variable: type, ..]): [returnType] {
expression
[return returnValue]
}
fun funName([variable: type, ..]): [returnType] = returnExpressionResult
fun square(x: Int): Int = x*x
fun getUserType(): String = "admin"
fun isLoggedIn(): Boolean = true
val accessLevel = when {
getUserType() == "admin" && isLoggedIn() -> "전체 접근 가능"
getUserType() == "user" && isLoggedIn() -> "제한된 접근"
!isLoggedIn() -> "로그인 필요"
else -> "접근 불가"
}
println("접근 권한: $accessLevel")
package org.example
fun main() {
returnVoid()
}
fun returnVoid(): Unit = println("Unit == void")
// fun returnVoid() = println("Unit == void")
- 함수의 선언 위치 상관 없음
- 중복 함수 선언 가능
package org.example
// fun sum(a: Int, b: Int): Int = a + b
fun main() {
fun sum(a: Int, b: Int): Int = a + b
val result = sum(1, 2)
println(result)
}
// fun sum(a: Int, b: Int): Int = a + b
parmeter/argument
- call-by-value
- parameter immutable(val)
-
**Position(Keyword) → Default → Vararg → (Default Keyword) → Collection(Container) parameter** 순서 paramVal: type = default- parameter initialize 가능
- call-by-position → initialize(python과 유사)
fun demo(
x: Int,
y: Int = 10,
vararg nums: Int,
flag: Boolean = false,
items: List<String> = listOf("Z")
) {
println("x=$x, y=$y, nums=${nums.toList()}, flag=$flag, items=$items")
}
fun main() {
demo(x = 1, 20, 30, 40, flag = true, items = listOf("A", "B"))
}
>>>
x=1, y=20, nums=[30, 40], flag=true, items=[A, B]
vararg
- 가변 인자(variable number of arguments)
- 다수의 동일한 데이터 타입(자료형)의 매개 변수를 처리
vararg varable: typevararg: 가변 인자를 받을 수 있는 키워드- container를 unpack하는 것이 아닌 복수개의 인자를 받음
- container도 하나의 type으로 지정
*: spread operation- unpack array
vararg의 argument
package org.example
fun varargParams(vararg vars: Char) = println(vars)
fun main() {
varargParams('a', 'b', 'c') // abc
val charArray = charArrayOf('a', 'b', 'c')
varargParams(*charArray) // abc
}
lambda
{ (parameter) -> expression }run lambdaFunlambdaFun(scope 함수) 실행- Unit fun 실행
fun main() {
val isSumEven = { x: Int, y: Int -> if ((x+y)%2==0) "true, " + (x + y).toString() else "false" }
val printsum = { println(isSumEven(1,1)) }
printsum()
run { println("run lambda fun") }
// run { str: String -> println(str) }("run") // error
}
- 일급 객체(first class)
- 기본 변수 타입처럼 행동하는 객체
- 함수의 인자, 반환값으로 사용 가능
- 변수에 담을 수 있음
- lambda도 일급 객체
- lambda를 파라미터로 받는 함수를 고차 함수 라고 함(이게 뭐라고 용어까지 있냐)
- 2중 함수 생성
- lambda가 마지막에 올 경우 lambda를 인자 외부에 선언 가능
fun funName(..., lambdaName: (paramsType) -> returnType, ...)
fun highFunc(sum: (Int, Int) -> Int, a: Int, b: Int): Int = sum(a, b)
fun nestedFunc(a: Int, b: Int): Int {
val sum = { x: Int, y: Int -> x + y}
return sum(a, b)
}
fun main(){
// highFunc({ x, y -> x + y }, a, b)) == nestedFunc(a, b)
println(highFunc({ x, y -> x + y }, 10, 20))
println(nestedFunc(10, 20))
}
fun highFunc(a: Int, b: Int, sum: (Int, Int) -> Int) = println(sum(a, b))
fun main(){
highFunc(10, 20, { x, y -> x + y })
highFunc(10, 20) { x, y -> x + y }
}
fun funName(lambdaName: () -> Unit){ lambdaName(); ... }- parameter, return 값이 없는 경우 바로 실행 가능한 lambda 생성 가능
Unit명시적 선언 필요
fun runLambda(a: Int, action: () -> Unit) {
println(a)
action()
action()
action()
action()
}
fun main(){
runLambda(1) { println("abc") }
}
예제
fun floatAvg(first: Float = 0f, vararg nums: Float): Double {
var length = nums.size
if (length == 0) return first.toDouble()
return (first.toDouble() + nums.sum()) / (length + 1)
}
fun main(){
val floatArray = floatArrayOf(1.0f, .5f, .5f)
println(floatAvg()) // 0.0
println(floatAvg(1.0f)) // 1.0
println(floatAvg(10.0f, *floatArray)) // 3.0
}
fun main(){
val isEven = { x: Int -> x%2==0 }
println(isEven(2))
isEvneFun(2) { x: Int -> x%2==0 }
}
fun isEvneFun(x: Int, result: (Int) -> Boolean) = println(result(x))
C
Contents
