* 이 글은 인프런 강의 <[입문편] 안드로이드를 위한 코틀린(Kotlin) 문법>을 보고 정리한 글입니다.
람다 (Lambda)
fun main() {
println(sumString("1", "2"))
println(sumStringTwo("1", "2"))
println(sumStringTypeTwo("1", "2"))
}
fun sumString(a : String, b : String) : String {
return "string1 : $a string2 : $b"
}
val sumStringTwo = {a : String, b : String -> "string1 : $a string2 : $b"}
val sumStringTypeTwo : (String, String) -> String = {a, b -> "string1 : $a string2 : $b"}
람다 = 즉시 표현식
{ } = 실행내용
-> = 그래서, 출력값은
{ } 안에 자료형을 선언하거나
자료형을 먼저 선언하고 { } 실행내용 씀
고차함수 (High-Order Function)
fun main() {
printTest("abc")
highPrintTest(::printTest) // 고차함수 '::'
}
fun printTest(str : String) {
println(str)
}
fun highPrintTest(operation : (String) -> Unit) {
operation("bbb") // printTest("bbb")
}
함수가 f(x)라면
고차함수 = f(f(x))
operation = 함수 안에 넣을 함수
:: = 함수 선언시 안에 넣을 함수 앞에 씀
제네릭 (generic)
fun main() {
val box1 = Box(10) // Int 타입
println(box1.value)
val box2 = Box("10") // String 타입
println(box2.value)
testFun("a") // Int 타입
testFun(123) // String 타입
}
class Box<T>(test : T) { // 타입캐스팅 ㄴㄴ
var value = test
}
fun <T> testFun(a : T) { // 타입캐스팅 ㄴㄴ
println(a)
}
제네릭 = 타입캐스팅 ㄴㄴ (타입이 무엇인지 상관 안함)
class 이름 다음에 <T> 씀. 자료형은 T
fun 이름 전에 <T> 씀. 자료형은 T
Object
fun main() {
val test1 = TestClass()
val test2 = TestClass()
test1.count = 10
println(test1.count) // 10
println(test2.count) // 0
val test3 = testObject
val test4 = testObject
test3.count = 10
println(test3.count) // 10
println(test4.count) // 10 (전역)
val test5 = TestObjectClass()
val test6 = TestObjectClass()
test5.plusBtn()
println(TestObjectClass.number) // 1
test5.plusBtn()
println(TestObjectClass.number) // 2
test6.minusBtn()
println(TestObjectClass.number) // 1 (전역)
}
class TestClass { // 그냥 클래스
var count = 0
}
object testObject{ // object
var count = 0
}
class TestObjectClass {
companion object { // 클래스 안의 object
var number = 0
}
fun plusBtn() {
number++
}
fun minusBtn() {
number--
}
}
object = 객체 한 개만. 전역으로 사용.
companion = class 안에 object를 쓰기 위해 앞에 붙임.
지연 초기화(lateinit / lazy)
fun main() {
lateinit var lateString : String // 미리 변수를 선언하고 나중에 값을 넣을 때 사용
lateString = "a"
lateString = "b" // 변경가능
println(lateString) // b
val lazyStirng : String by lazy { // 나중에 이 값들을 사용
println("프린트")
"lazyTestString"
} // 변경불가
println(lazyStirng) // "프린트" "lazyTestString"
}
lateinit = 미리 변수 선언 후 나중에 값을 넣겠음.
var 이전에 씀. 변경 가능.
by lazy = 나중에 값을 사용하겠음.
자료형 후에 씀. 변경 불가.
infix function
fun main() {
println(10 sum1 20) // 30
println(10 sum2 20) // 30
println("apple" sum3 "grape") // applegrape
println("사과" sum4 "포도") // 사과포도
println(10 showList 15) // [10, 11, 12, 13, 14, 15]
}
infix fun Int.sum1(num : Int) : Int = this + num
infix fun Int.sum2(num : Int) : Int {
return this + num
}
infix fun String.sum3(abc : String) : String = this + abc
infix fun String.sum4(abc : String) : String {
return this + abc
}
infix fun Int.showList(num : Int) : List<Int> {
val list = mutableListOf<Int>()
for (i in this..num) {
list.add(i)
}
return list
}
infix = 중간에서 역할
this = infix 함수 사용시 앞단
인수는 infix 함수 사용시 뒷단
scope function
fun main() {
//let : null이 아닐 때 동작, null일 때 동작 X
val str : String? = "hi"
val length = str?.let {
println(it) // "hi"
it.length
}
println(length) // 2
val str2 : String? = null
val length2 = str2?.let {
println(it)
println("실행") // 실행되지 않음
it.length
}
println(length2) // null
// with : 내부에서 함수 호출시
val numbers = mutableListOf("a", "b", "c", "d")
println(numbers.first()) // "a"
println(numbers.last()) // "d"
val firstAndLast = with(numbers) {
"${first()} ${last()}"
}
println(firstAndLast) // "a d"
}
let = null일 때 동작 안함.
with = 컨텍스트 내부에서 함수호출.
fun main() {
// run : 객체 초기화, 반환값 계산
val service = multiPortService("www.naver.com", 80)
val result = service.run {
query(prepareRequest() + " to port $port")
}
println(result) // 결과 query 기본 요청 url www.naver.com to port 80
//apply : 값은 반환 X, 객체 구성에 대해 사용
val tester = Person("Tester").apply{
age = 21
city = "Busan"
}
println(tester) // Person(name=Tester, age=21, city=Busan)
// also : 객체 추가작업
val numbers = mutableListOf(1, 2, 3, 4)
numbers.also {
println("$numbers 여기에서 5를 추가합니다.")
}.add(5)
println(numbers) // [1, 2, 3, 4, 5]
}
class multiPortService(var url : String, var port : Int) {
fun prepareRequest() : String = "기본 요청 url $url"
fun query(request : String) = "결과 query $request"
}
data class Person(
var name : String,
var age : Int = 0,
var city : String = ""
)
run = 객체 반환값 계산
apply = 객체 구성
also = 객체 추가작업
enum class
fun main() {
println(Direction.NORTH) // NORTH
Direction.values().forEach {
println(it) // NORTH SOUTH WEST EAST
}
val direction = Direction.EAST
when(direction) {
Direction.NORTH -> {
println("N")
}
Direction.SOUTH -> {
println("S")
}
Direction.WEST -> {
println("W")
}
Direction.EAST -> {
println("E")
}
} // E
val color = Color.RED
when(color) {
Color.RED -> {
println(Color.RED.colorName)
}
Color.GREEN -> {
println(Color.GREEN.colorName)
}
Color.BLUE -> {
println(Color.BLUE.colorName)
}
} // "빨강"
println(Device.DEVICEON.status) // ON
Device.DEVICEON.status = "OFF" // 값 변경
println(Device.DEVICEON.status) // OFF
}
enum class Direction {
NORTH, SOUTH, WEST, EAST
}
enum class Color(val colorName : String) {
RED("빨강"),
GREEN("초록"),
BLUE("파랑")
}
enum class Device(var status : String) {
DEVICEON("ON"),
NETWORK("OFF"),
LOCATION("SEOUL")
}
enum class = 나열