2015년 6월 21일 일요일

안드로이드를 위한 Swift - Kotlin을 아시나요?

얼마전 구글I/O와 관련하여 나프다를 녹음하던중 코틀린Kotiln에 대하여 알게 되었습니다.
국내엔 아직 제대로 소개된 바가 없으므로 궁금해 하시는 분들을 위해 간단히 설명하자면 IntelliJ로 유명한 젯브레인즈Jetbrains가 만든 JVM언어인데, 언어자체의 특징을 한마디로 설명하자면 그냥 JVM에서 돌아가는 스위프트Swift입니다. 정확히 말을 하자면 코틀린은 2011년에, 스위프트는 2014년에 발표되었으므로 스위프트는 코틀린을 베꼈다고 말 해도 무방할 정도지만 언어의 인지도 면에서는 스위프트가 압도적이라고 할 수 있으므로 코틀린진영에서는 다소 억울한 마음이 들 수 도 있겠습니다.
우선 코틀린에 대해서 특징을 간단히 정리 해 보자면 다음과 같습니다.
  • 젯브레인즈가 만든 JVM언어
  • 컴파일 언어이자 정적 형 체크 언어
  • 문법이나 기능등에 있어 스위프트와 거의 흡사
  • 따라서 객체지향 언어이면서 함수형 프로그래밍의 특징들을 상당수 포함하고 있음
  • 5월 29일 발표된 M12릴리스에는 어노테이션을 중심으로 코틀린만의 변화가 추가됨
  • JAVA를 소스코드레벨에서 코틀린으로 변환 가능함
  • 코틀린 코드를 자바스크립트JavaScript로 변환 가능함
  • 안드로이드 앱 개발이 가능
코틀린에 대한 정보를 찾던중 스위프트와의 비교를 비롯해 여러가지 특징들이 잘 정리된 Matsuda Shoichi님의 기사 “Swift로 안드로이드 어플을 만든다고!!?“를 발견하였기에 그 내용을 번역해 소개해 봅니다. 이 자리를 빌어 번역을 흔쾌히 허락해 주신 Matsuda Shoichi(shoma2da)님께 다시 한 번 감사의 말씀을 드립니다.

스위프트로 안드로이드 어플을 만든다고!!?

2014년 6월에 발표된 스위프트. 개인적인 감상 으로는 여러 가지 언어의 좋은 점만 가져와서 좋은 의미로서 별다른 허들없이 쓰기 쉽게 만든 아주 좋은언어라고 생각합니다.
그럼 스위프트로 안드로이드개발이 된다고요?
뭐 아직 거기까진 아닙니다.
역자주: 이 글을 작성하던 도중 애플이 스위프트를 오픈소스화 하였습니다. 따라서 앞으로 스위프트가 JVM을 포함한 다른 플랫폼. 특히 안드로이드로 등장할 가능성이 매우 높아졌습니다. 개인적으로는 오라클과의 소송문제도 있고 해서 향후 구글이 코틀린을 안드로이드 개발언어로 전면적으로 도입할 가능성에 대해서 생각을 하고 있었는데 다소 상황이 복잡해지게 되었네요. 어찌되었든 안드로이드 공식개발툴인 안드로이드 스튜디오를 젯프레인즈가 제공하고 있는 이상 안드로이드를 위한 개발 언어로서 자바가 배재된다고 한다면 코틀린은 우선순위가 가장 높은 후보라는 생각입니다.
이번에 소개하고자 하는 것은 코틀린이라고 하는 언어인데요, 스위프트와는 세세한 부분에서 다른점이 있기는 하지만, 여러 언어들에서 장점을 가져오다보니 두 언어가 매우 비슷한 느낌입니다.

코틀린은 어떤 언어?

홈페이지는 여기입니다.
IntelliJ의 개발사인 젯브레인즈에서 개발된 언어 입니다.
데이터타입 추론이나 클로져, 패턴매칭등 함수형의 특징을 받아들인 객체지향 언어입니다.

코들린으로 안드로이드 앱을 만들기위해서는

완전 간단히 설명하자면 다음과 같습니다.
  1. (처음이라면) 안드로이드 스튜디오를 다운로드한다
  2. 안드로이드 스튜디오를 기동하고 New Project를 만든다
  3. 코틀린 도입방법을 참고로하여 build.gradle에 몇 줄의 설정을 추가 한다
  4. 코틀린으로 코드를 작성하고 실행!!

언어의 비교

그럼 스위프트와 어떠한점이 다른지 살펴보도록 하겠습니다.
The Swift Programming Language의 순서를 따라 비교해 보도록 하겠습니다.

변수 선언

불변 값의 선언이 let 또는 val 인가의 차이입니다.
  • Swift
var  myVariable  =  42 
myVariable  =  50 
Let  myConstant  =  42
  • Kotlin
var  myVariable  =  42 
myVariable  =  50 
val  myConstant  =  42

문자열 내에서의 변수

\ 또는 $ 의 차이군요
  • Swift
Let  apples  =  3 
Let  oranges  =  5 
Let  appleSummary  =  "I have \ (apples) apples" 
Let  fruitSummary  =  "I have \ (apples + oranges) pieces of fruit."
  • Kotlin
val  apples  =  3 
val  oranges  =  5 
val  appleSummary  =  "I have $ apples apples" 
val  fruitSummary  =  "I have $ {apples + oranges} pieces of fruit."

배열과 사전식 배열

약간 다르 네요.
  • Swift
var  ShoppingList  =  [ "catfish" ,  "water" ,  "tulips" ,  "blue paint" ] 
shoppingList [ 1 ]  =  "bottle of water" 

var  Occupations  =  [ 
    "Malcolm" :  "Captain" , 
    "Kaylee" :  "Mechanic" , 
] 
occupations [ "Jayne" ]  =  "Public Relations"
  • Kotlin
var  ShoppingList  =  array ( "catfish" ,  "water" ,  "tulips" ,  "blue paint" ) 
shoppingList [ 1 ]  =  "bottle of water" 

var  Occupations  =  hashMapOf ( 
    "Malcolm"  to  "Captain" , 
    "Kaylee"  to  " Mechanic " 
) 
occupations [ "Jayne" ]  =  "Public Relations"

for

Swift는 장소에 따라서는 () 를 생략 할 수 있지만 Kotlin은 필수 입니다.
  • Swift
Let  individualScores  =  [ 75 ,  43 ,  103 ,  87 ,  12 ] 
var  teamScore  =  0 
for  score  in  individualScores  { 
    IF  score  >  50  { 
        teamScore  + =  3 
    }  else  { 
        teamScore  + =  1 
    } 
} 
teamScore
  • Kotlin
val  individualScores  =  listOf ( 75 ,  43 ,  103 ,  87 ,  12 ) 
var  teamScore  =  0 
for  ( score  in  individualScores )  { 
    if  ( score  >  50 )  { 
        teamScore  + =  3 
    }  else  { 
        teamScore  + =  1 
    } 
} 
teamScore

Optinal Value

이 근처에서 언어의 특징이 나와 있네요. 
null에 대한 대응으로 모두 ? 를 사용한 문법을 채용하고 있습니다.
  • Swift
var  optionalString :  String ?  =  "Hello" 
optionalString  ==  nil 

var  optionalName :  String ?  =  "John Appleseed" 
var  greeting  =  "Hello!" 
IF  Let  name  =  optionalName  { 
    greeting  =  "Hello \ (name)" 
}
  • Kotlin
var  optionalString :  String ?  =  "Hello" 
optionalString  ==  null 

var  optionalName :  String ?  =  "John Appleseed" 
var  greeting  =  "Hello!" 
if  ( optionalName  ! =  null )  { 
    greeting  =  "Hello $ optionalName" 
}

값의 속박

모두 동일합니다
  • Swift
Let  interestingNumbers  =  [ 
    "Prime" :  [ 2 ,  3 ,  5 ,  7 ,  11 ,  13 ], 
    "Fibonacci" :  [ 1 ,  1 ,  2 ,  3 ,  5 ,  8 ], 
    "Square" :  [ 1 ,  4 ,  9 ,  16 ,  25 ], 
] 
var  Largest  =  0 
for  ( kind ,  numbers )  in  interestingNumbers  { 
    for  Number  in  Numbers  { 
        IF  Number  >  largest  { 
            largest  =  number 
        } 
    } 
} 
largest
  • Kotlin
val  interestingNumbers  =  mapOf ( 
    "Prime"  to  array ( 2 ,  3 ,  5 ,  7 ,  11 ,  13 ), 
    "Fibonacci"  to  array ( 1 ,  1 ,  2 ,  3 ,  5 ,  8 ), 
    "Square"  to  array ( 1 ,  4 ,  9 ,  16 ,  25 ) 
) 
var  Largest  =  0 
for  (( kind ,  numbers )  in  interestingNumbers )  { 
    for  ( Number  in  Numbers )  { 
        if  ( number  >  largest )  { 
            largest  =  number 
        } 
    } 
} 
largest

Range

똑같네요
  • Swift
var  firstForLoop  =  0 
for  I  in  0..3  { 
    firstForLoop  + =  i 
} 
firstForLoop
  • Kotlin
var  firstForLoop  =  0 
for  ( I  in  ( 0..3 ))  { 
    firstForLoop  + =  i 
} 
firstForLoop

Function

반환 값 주위가 약간 다르지만 거의 똑같 네요.
  • Swift
Func  greet ( name :  String ,  day :  String )  ->  String  { 
    return  "Hello \ (name), today is \ (day)" 
} 
greet ( "Bob" ,  "Tuesday" )
  • Kotlin
Fun  greet ( name :  String ,  day :  String ) : String  { 
    return  "Hello $ name, today is $ day." 
} 
greet ( "Bob" ,  "Tuesday" )

Function 중첩

  • Swift
양쪽 다 function 안에 function을 선언 할 수 있습니다
Func  returnFifteen ()  ->  Int  { 
    var  y  =  10 
    Func  add ()  { 
        y  + =  5 
    } 
    add () 
    return  y 
} 
returnFifteen ()
  • Kotlin
Fun  returnFifteen () : Int  { 
    var  y  =  10 
    Fun  add ()  { 
        y  + =  5 
    } 
    add () 
    return  y 
} 
returnFifteen ()

Function 객체

문법은 여러가지 다른점이 있지만 기본적인 개념은 동일합니다
  • Swift
Func  hasAnyMatches ( list :  [ Int ]  condition :  Int  ->  Bool )  ->  Bool  { 
    for  Item  in  List  { 
        IF  Condition ( item )  { 
            return  true 
        } 
    } 
    return  false 
} 
Func  lessThanTen ( number :  Int )  ->  Bool  { 
    return  number  <  10 
} 
var  Numbers  =  [ 20 ,  19 ,  7 ,  12 ] 
hasAnyMatches ( numbers ,  lessThanTen )
  • Kotlin
Fun  hasAnyMatches ( list :  Array < Int >  condition :( Int )  ->  Boolean ) :  Boolean  { 
    for  ( Item  in  List )  { 
        if  ( condition ( item ))  { 
            return  true 
        } 
    } 
    return  false 
} 
val  lessThanTen :( Int )  ->  Boolean  =   {  number  -> 
    number  <  10 
} 
var  Numbers  =  array ( 20 ,  19 ,  7 ,  12 ) 
hasAnyMatches ( numbers ,  lessThanTen )

익명 함수

거의 똑같 네요
  • Swift
var  Numbers  =  [ 20 ,  19 ,  7 ,  12 ] 
numbers . map ({ 
    ( number :  Int )  ->  Int  in 
    Let  result  =  3  *  Number 
    return  result 
})
  • Kotlin
var  Numbers  =  array ( 20 ,  19 ,  7 ,  12 ) 
numbers . map ({ 
    val  result  =  3  *  it 
    result 
})

간단한 클래스

  • Swift
class  Shape  { 
    var  numberOfSides  =  0 
    Func  simpleDescription ()  ->  String  { 
        return  "A shape with \ (numberOfSides) sides." 
    } 
} 
var  Shape  =  Shape () 
shape . numberOfSides  =  7 
var  shapeDescription  =  shape . simpleDescription ()
  • Kotlin
class  Shape  { 
    var  numberOfSides  =  0 
    Fun  simpleDescription () : String  { 
        return  "A shape with $ numberOfSides sides." 
    } 
} 
var  Shape  =  Shape () 
shape . numberOfSides  =  7 
var  shapeDescription  =  shape . simpleDescription ()

생성자가있는 클래스

Kotlin 생성자는 클래스 명의 직후에 쓸 수 있도록 하여 간단한 것이라면 보다 간결하게 쓸 수 있습니다
  • Swift
class  NamedShape  { 
    var  numberOfSides :  Int  =  0 
    var  name :  String 

    init ( name :  String )  { 
        self . name  =  name 
    } 

    Func  simpleDescription ()  ->  String  { 
        return  "A shape with \ (numberOfSides) sides." 
    } 
}
  • Kotlin
class  NamedShape ( var  name : String )  { 
    var  numberOfSides :  Int  =  0 

    Fun  simpleDescription () : String  { 
        return  "A shape with $ numberOfSides sides." 
    } 
}

결론

오늘은 여기까지 하고 마치도록 하겠습니다.
어떠신가요?
스위프트와 코틀린, 활용 용도에 있어서는 iOS와 안드로이드라고 하는 차이가 있을 뿐이고 대단히 비슷한 모습과 특징을 지닌 언어 입니다.
이번엔 소개를 생략했지만 상속이라던지 Function의 좀더 깊숙한 부분이라고 하더라도 기본적인 개념은 같기때문에 어느 한쪽에서 다른쪽으로 넘어가기가 쉽습니다.
이 글을 계기로 iOS개발자 여러분들도 안드로이드 개발에 영역을 넓혀 가실 수 있다면 기쁘겠습니다.

관련 읽을거리들