Code with Joyce 님의 영상,
부스트코스 코틀린 강좌,
오준석의 안드로이드 생존코딩 책(2판)을 기반으로 작성하였습니다
람다식은 우리가 value 처럼 다룰 수 있는 익명함수이다.
val 람다이름 : Type = {argumentList -> codBody}
val square: (Int) -> (Int) = { number -> number * number }
val square = { number: Int -> number * number }
앞이든 뒤든 타입을 한 곳은 명시해줘야함 (그래야 타입 추론 가능)
val nameAge : (String,Int) -> String = { name:String, age:Int ->
"my name is ${name} im ${age}"}
람다식의 Type은 순서대로 써줘야 함!
매개변수는 여러개일 수 있으므로 괄호를 써주자!
↪️ 만약 람다식에서만 RETURN 을 하고 싶다면?!
label을 이용한다
: Single Abstract Method 변환으로, 메서드가 하나인 인터페이스를 구현할 때 함수를 작성함.
button.setOnClickListener(object:View.OnClickListener{
override fun onClick(v: View?){
//TODO
}
})
button.setOnClickListener{
it.visibility = View.GONE
}
it는 View? 타입의 v인수를 가리킴.
-> 코틀린에서는 인터페이스 대신 함수를 사용하는 것이 바람직.
val calculateGrade: (Int) -> String = {
when (it) {
in 0..50 -> "fail"
in 51..80 -> "pass"
in 81..100 -> "perfect"
else -> "Error"
}
}
람다는 마지막 표현식이 리턴
100까지만 범위를 나누면 범위이외의 값에서는 return을 못하므로
else 절을 꼭 적어줘야 한다
fun invokeLamda(lamda:(Double)->Boolean):Boolean{
return lamda(5.2343)
}
Double형을 받아 Boolean을 리턴하는 람다식을 리턴하는 함수이다.
함수를 main 함수에서 호출하면
fun main(){
val lamda={number : Double -> number == 4.3212}
println(invokeLamda(lamda)) // false 출력
println(invokeLamda { true }) // true 출력
println(invokeLamda { it>3.22 }) // 넣는파라미터 1개가 3.22보다 크면 true
}
button.setOnClickListener(object : View.OnClickListener{
override fun onClick(p0: View?) {
//TODO("Not yet implemented")
}
})
button.setOnClickListener { //TODO("Not yet implemented") }
setOnClickListener는 위의 두 조건을 만족하기에 람다식 적용가능
데이터클래스는 자바의 POJO 클래스를 데이터만 다루는 훨씬 간편한 문법이다.
데이터클래스 여러 개도 한 파일안에서 생성가능하며,
생성자, getter와setter, toString(), hashCode(), equals(), copy(), component1() 등
다양한 메소드를 컴파일러가 자동으로 만들어줌
데이터 클래스 작성 시 기본 생성자 에 val/var로 지정한 매개변수가 1개 이상 있어야 함
abstract, open, sealed, inner 키워드 사용 불가함
구조분해를 지원해줌 = property를 순서대로 할당해줌
val (name,age) = Person("김민주", 24)
기존 자바에서 일일이 적어줘야했던 메소드들이 자동으로 생성되니 아주 편하다👍
data class Ticket(val companyName: String, val name: String, var date: String, var seatNumber: Int)
fun main(){
val ticketA = Ticket("koeanAir","minju","2022-06-11", 1)
println(ticketA) //객체 내용 출력
}
일반 클래스라면 메모리 주소값이 출력될텐데
DataClass라서 객체의 내용이 출력된다
Ticket(companyName=koeanAir, name=minju, date=2022-06-11, seatNumber=1)
Companion Object는 클래스 내부에서 선언하며, 1개만 선언할 수 있다.
동반객체는 자바의 static과 비슷한 개념이지만 static처럼 동작하는 오브젝트 객체이다!
private property나 method를 읽어올 수 있게끔 한다.
class Book private constructor(val id:Int, val name:String){
companion object : IdProvider {
override fun getId(): Int {
return 444
}
val myBook = "kotlin basic"
fun create() = Book(getId(), myBook)
}
}
interface IdProvider{
fun getId() : Int
}
fun main(){
val book = Book.Companion.create() // 이름이 없다면
val book2 = Book.a.create() //companion object a { 라면
val book3 = Book.create() //Companion 또는 이름 생략가능
val bookId = Book.getId()
println("${book.id} ${book.name}")
}
Output : 444 kotlin basic
오브젝트는 컴파일될 때 한 번만 만들어지는 객체로,
Singleton Pattern 이며, Thread-safe 하다.
사용되지 않아도 생성되기 때문에 메모리에 인스턴스가 존재한다.
object CarFactory{
val cars = mutableListOf<Car>()
fun makeCar(horsePower: Int) : Car{
val car =Car(horsePower)
cars.add(car)
return car
}
}
data class Car(val horsePower : Int)
fun main(){
val car = CarFactory.makeCar(10)
val car2 = CarFactory.makeCar(200)
println(car)
println(car2)
println(CarFactory.cars.size)
}
Object | Companion object | |
---|---|---|
선언 | 전체가 싱글톤 객체 | 클래스 내 일부분이 싱글톤 객체 |
초기화 | 사용될 때 | 속한 클래스가 메모리에 올라갈 때 |
: 원래 있던 클래스에 기능을 추가하는 함수.
.확장함수이름
으로 작성만약 숫자가 짝수인지 판별하려면,
fun Int.isEven() = this % 2 == 0
val a = 5
println(a.isEven()) //false
만약 String class 에 무언가 추가하고 싶다면,
val mara : String.() -> String = {
this + " Maratang is the best!"
}
fun main(){
val a = "minju said"
println(a.mara()) // "minju said Maratang is the best!" 출력
}
람다랑 같이 쓰였다.
fun extendsString(name:String, age:Int):String{
val introduceMyself : String.(Int) -> String = {
"I am ${this} and ${it} years old"
}
return name.introduceMyself(age)
}
this는 확장함수가 불러낸 String 오브젝트이고
파라미터가 Int 하나이므로 파라미터가 하나면 it으로 지정가능
: 다른함수를 인수를 받거나 반환하는 함수.(higher-order fun)
fun add(a:Int, b:Int, callback:(sum: Int) -> Unit){
callback(a+b)
}
//작성한 고차함수를 사용
add(5,3,{println(it)})
//함수는 {}로 감싸고, 내부반환값을 it으로 접근
: 블록에 자기자신을 인수로 전달하고 결과를 반환하는 함수.
val result = str?.let{
Integer.parseInt(it)
}
null이 아닐 때만 str을 정수로 변환하여 반환해주는 코드.
if문을 쓰는 것보다 훨씬 간결하게 가능함.
: 인수를 객체로 받으면서 블록에 리시버 객체로 전달하는 함수.
with(str){
println(toUpperCase()) //this 생략
}
: 블록에 객체 자신이 리시버 객체로 전달되고 이 객체가 반환되는 함수.
val result = car?.apply{
car.setColor(Color.red)
car.setPrice(3000)
} // result에는 값이 변경된 car객체가 저장됨
val avg = run{
val korean = 100
val english = 80
val math = 98
(korean+english+math) / 3.0
}
str?.run{
println(toUpperCase()) //this 생략
}
: 객체를 사용한 후 자동으로 close() 메소드를 호출해주는 함수