let은 인자로 받는 람다식 내에서 반환값을 만들어서 반환한다.
also는 인자로 받는 람다식은 반환값이 없다. also 함수 자체에서 객체 T를 반환한다. (also를 호출한 객체)
즉 블록 내의 내용과 관계없이 T를 반환한다.
{}내의 내용과 관계없이 also는 m을 다시 반환하므로 출력값은 1이다.
let과 마찬가지로 객체를 복사해서 block에서 처리하므로 값 역시 그대로이다.
fun main() {
//데이터타입 정의
data class Person(val name:String,var skill:String)
//생성자로 객체 생성
var person :Person = Person("Son","Kotlin")
//let
val ret1 = person.let{
it.skill="Java"
"skill changed"
}
println("ret1 = $ret1")
println("person.skill = ${person.skill}")
//also
val ret2 = person.also{
it.skill = "Python"
"skill changed"
}
println("ret2 = $ret2")
println("person.skill = ${person.skill}")
}
ret1 = skill changed
person.skill = Java
ret2 = Person(name=Son, skill=Python)
person.skill = Python
데이터타입 Person을 정의하고 객체를 생성한다.
먼저 let을 이용해서 객체의 skill 멤버값을 바꾼다.
it은 호출한 대상을 복사해서 가져온다고 했는데 참조를 복사한 것이기 때문에 실제 객체에 변화가 발생한다.
즉 지금 예시는 C에서의 vall by reference 방식처럼 person을 사용한 것이라 person의 필드값이 also의 block에서 처리한 대로 바뀐다.
하지만 위의 예시에서는 C에서의 call by value 방식처럼 값 자체를 복사해서 block에서 처리해서 원본값은 바뀌지 않았다.
다시 현재 예시에서는 person의 skill 멤버가 Java로 변경된다. 그리고 let은 반환값이 있으므로 마지막 문장인 skill changed를 반환한다.
also도 let과 마찬가지로 person의 skill 멤버를 Python으로 변경하지만 람다식의 return값은 없고 also 자체가 자신을 호출한 객체인 person을 반환해서 ret2는 person객체를 출력하고 있다.
긴 코드를 let과 also를 이용해서 간단한 표현이 가능하다.