인터페이스 2 1. 타입 단언 이전에 interface 1편에서 interface 변수는 할당 받은 타입의 고유 메서드를 사용할 수 없다고 했다. 즉, 자바에서처럼 인터페이스와 구현체 모두 존재하는 메서드가 아닌, 구현체 내부에서만 존재하는 메서드는 인터페이스에서 사용할 수 없는 것처럼 말이다. 그렇다면 자바에서는 어떻게 했는가?? 타입을 변환해주면 되었다. go에서의 인터페이스 역시도 타입을 변환하면 될 것 같다. 참고로 go에서의 타입 변환은 다음과 같다. value_float := 1.2 value_int := int(value_float) 이전에 사용했던 예제를 가져와보자 package main import "fmt" type TapeInterface interface { Play(string) ..
인터페이스 1. 인터페이스 자바에서 객체 지향과 디자인 패턴의 핵심은 인터페이스이다. go 역시도 인터페이스를 지원하는 아주 재밌는 언어이다. 인터페이스를 사용하는 가장 큰 이유는 어떤 값이 어떤 특징 타입을 갖는지 관심이 없는 경우가 있기 때문이다. 그 값이 무엇인지보다는 그 값으로 어떤 일을 할 수 있는 지에 대해서 더 관심을 두는 경우가 있다. 즉, 어떤 값에서 특정 메서드를 호출할 수 있는 지가 주요 관심사인 것이다. 가령, 자판기가 있다면 버튼을 눌러서 음료수를 꺼내는게 우리의 관심사이지, 이 자판기가 어느 제조사에서 만들어졌는지는 중요하지 않다. 이럴 때 사용하는 것이 바로 인터페이스인 것이다. 1.1 동일한 메서드를 가진 서로 다른 타입 다음의 예제를 보도록 하자 package main im..
구조체 2 지난 번에는 구조체를 선언하고, 이를 사용하는 방법을 배웠다. 그러나, 구조체는 이것이 다가 아니다. c언어에서는 구조체에 함수를 넣어줄 수 없지만, c++이 되면서 구조체에 함수를 넣어줄 수 있었다. 이것이 필요한 이유는 사용자 정의 타입에서 메서드를 정의하면 메서드 이름이 같지만 다른 사용자 정의 타입 간에는 충돌이 발생하지 않기 때문이다. golang 역시도 마찬가지 이다. 다음의 문제 상황을 해결해보자 package main import "fmt" type Coffee struct { name string price int } type Tea struct { name string price int } func drinkCoffee(coffee Coffee, money *int) { fm..
맵(map) 1. 맵이란 슬라이스나 배열은 데이터를 저장하는 자료구조이다. 그러나, 이들의 가장 큰 단점은 인덱스로만 검색을 해야한다는 것이다. 만약 내가 원하는 데이터를 KEY-VALUE 형식으로 가지고 오고싶으면 어떻게 해야할까?? 가령, 가수를 검색한다고 하면 key는 ph1이고 노래는 value일 것이다. 배열이나 슬라이스로 저장되어 있다면 모든 자료구조를 박박뒤져가며 key가 일치하는 데이터를 가져와야 할 것이다. 그러나, 이는 매우 불편하고 성능상의 문제도 치명적이다. 이에 따라 map이라는 자료구조가 존재하게 된 것이다. 맵은 key와 value로 이루어진 자료구조로 자신이 원하는 타입의 key로 값을 가져오는 방식이다. 2. map 선언 map을 선언하는 방법은 map이라는 키워드를 사용함..
슬라이스 ( slice ) 1. 슬라이스란? go에서는 값을 추가하여 확장할 수 있는 데이터 구조가 있는데, 이를 슬라이스라고 한다. 배열과 마찬가지로 슬라이스도 복수 개의 원소로 이루어져 모든 원소는 동일한 타입을 갖는다. 그리고 핵심적인 것은 슬라이스는 배열과 달리 슬라이스 끝에 원소를 추가할 수 있다는 것이다. 2. 슬라이스의 선언과 초기화, 할당 슬라이스의 선언은 배열과 다를 바 없다. 단지 배열의 선언에서 사이즈를 안써주면 슬라이스가 되는 것이다. var 슬라이스이름 []타입 타입 앞에 있는 [] 에 사이즈를 꼭 비워주면 슬라이스가 된다. 그러나, 슬라이스는 배열과 같이 []타입{값,값,...}으로 초기화할 수 없고 make(타입, 사이즈) 를 이용해야 한다. make(타입, 사이즈) 에서 사이..
GO에서의 배열 1. 배열 선언 지난번 포인터 변수를 선언했을 때 재밌었던 것은 변수의 타입 앞에 *(에스테리스크)를 썼다는 것이다. var pIntValue *int; 배열 역시도 마찬가지이다. 결국 배열의 사이즈를 나타내는 []을 변수 타입 앞에 써주기만 해주면 되는 것이다. var 배열이름 [사이즈]타입 다음과 같이 선언해주면 되는 것이다. 그럼 사용방법을 한번 보도록 하자 package main import "fmt" func main() { var array [10]string array[0] = "hello" array[1] = "world" fmt.Println(array[0]) // hello fmt.Println(array[1]) // world } 2. 배열 리터럴 배열이 가질 값을 미..
package 1. 패키지란? 패키지는 유사한 기능을 수행하는 코드들의 집합이다. fmt, strings 등도 모두 패키지이다. 코드의 일부가 여러 프로그램 간에 공유되는 경우 코드를 패키지로 분리하는 것을 고려해 볼 수 있다. 그러나, golang의 패키지 시스템은 자바나 c/c++처럼 그렇게 간단하지는 않다. 일단, GOPATH와 GOROOT에 대해서 알아보자 2. GOPATH, GOROOT GOROOT go를 설치했을 때 Go관련 실행 파일, sdk 등이 위치한 곳으로, 이곳에 파일을 위치하면 go파일들은 모두 참조할 수 있다. GOPATH bin, pkg, src 폴더가 위치하는 path로 go get 명령어를 통해 받은 패키지나 라이브러리, 소스파일이 위치하는 곳이다. 즉, ide를 통해서 go..
포인터 (Pointer) 1. 포인터의 선언 포인터 변수는 주소를 받아, 주소로 변수를 제어하는 기능이다. pointer가 남아있는 언어가 별로 없는데 golang은 포인터를 지원한다. 이는 굉장히 강력한 기능이고 golang에 있어서 큰 장점 중 하나라고 생각한다. 포인터에는 타입과 에스테리스크(*)가 필요하다. var 포인터변수 *포인터타입 = &변수 일반 변수 선언에서 *를 만 추가해서 사용하면 된다. 또한, 변수의 주소를 주소싶을 때는 &를 사용하면 된다. package main import "fmt" func main() { var intValue int = 10 var pIntValue *int = &intValue fmt.Print(*pIntValue) // 10 } 단축 선언을 사용하여 더..