* 개발 언어별 지원
기능 | Go | C++ | Java |
Class | X | O | O |
Inheritance | X | O | O |
Overloading | X | O | O |
GC(Garbage Collector) | O | X | O |
Pointer | O | O | X |
Pointer 연산 | X | O | X |
Import/Package | O | O(include, namespace) | O |
Interface | O | O(template) | O |
nil | O | O(NULL, 0) | O(null) |
Implicit type conversion | X | O | O |
* 변수 선언
var a int
var b[10]int
var c, d *int
// var 를 사용하여 그룹으로 묶기
var(
a int
f float64
s string
)
// 선언 시 값을 할당하는 경우 type 생략 가능
var i = 4
// 함수 내에서만 사용되면 ':=' 로 var, type 생략 가능
i := 1
- var a int : 변수 a 는 정수형이다. (Variable a is interger.)
* if 문, while 문
if i == 0 { // () 를 생략가능.
f()
}
if i == 0 // 컴파일 에러. ';' 이 자동으로 삽입되어 if i == 0 ; 이 된다.
{
f()
}
for condition { // while 이라는 키워드가 없다.
...
}
* 접근 제한자 - public, private
함수의 첫글자가 대문자로 시작하면 외부 모듈에서 접근 가능한 public, 소문자로 시작하는 경우 외부 모듈에서 접근할 수 없다.
* 변수 선언 초기화 값
numeric : 0
boolean : false
string : ""
pointer, map, slice, channel : nil
struct : zeroed struct
* 인터페이스
type Drawer interface {
Draw()
}
type Circle struct {
r int
}
func (c Circle) Draw() {
fmt.Println("Circle is Draw : ", c.r)
}
type Rectangle struct {
w, h int
}
func (r Rectangle) Draw() {
fmt.Println("Rectangle is w=", r.w, " h=", r.h);
}
func DrawForm(d Drawer) {
d.Draw()
}
func main() {
var myC Circle = Circle{5}
var myR Rectangle = Rectangle{3,4}
DrawForm(myC)
DrawForm(myR)
}
* switch 문
switch i {
case 0, 1 : // i 가 0 또는 1 인 경우 수행한다.
doSomeThing()
}
switch { // switch 만 있는 경우 true 를 기본값으로 가진다
case i < 0:
f1()
case i == 0:
f2()
case i < 0:
f3()
}
* 함수
func add(a, b int) int {
return a+b
}
func f(i int, j int, k int, s string, t string)
// 동일 함수 인자 묶기
func f(i,j,k int, s,t string)
// 두개 이상의 값을 반환
func add(a, b int) (int, bool) {
return a+b, true
}
* 배열
var ar [3]int // 배열 선언
len(ar) // 사이즈 구하기
[3]int{1,2,3} // 3개 정수를 갖는 배열
[10]int{1,2,3} // 10 개 정수를 배열 중 처음 3개가 값을 대입
[...]int{1,2,3} // {} 안에 엘리먼트의 갯수로 결정되어 [3]int 배열이 된다.
* Swap
두 변수에 들어있는 값을 서로 맞바꾸는 연산인데, 다른 언어에서는 임시변수를 사용하지만 다음 코드로 된다.
i, j = j, i
* Slice
포인터 연산이 없는 대신 배열의 특정 부분을 참조하기 위해 사용.
var ar [10]int = [10]int{1,2,3,4,5,6,7,8,9,10} // 배열 ar
var a []int // 슬라이스 a
a = ar[7:9] // ar 의 7,8 번째 값을 참조한다
len(a) // a 의 사이즈는 2
a = ar[:n] // ar[0:n] 배열의 0 번째부터 n-1 번째까지 참조한다.
a = ar[n:] // ar[n:len(a)] 배열의 n 번째부터 끝까지를 참조한다.
a = ar[:] // ar[0:len(ar)] 배열의 전체를 참조한다.
* defer 키워드
아래 코드는 Open -> ReadAll -> Close 순으로 호출된다. Open, Close 같이 열고 닫는 동작이 쌍으로 존재하는 경우 두 함수를 함께 붙여 사용할 수 있고, 마무리 동작을 잊지 않게 도와주는 효과가 있다.
func data(fileName string) string {
f := os.Open(fileName)
defer f.Close()
contents := io.ReadAll(f)
return contents
}
* 암시적 형변환(implicit type conversion)
var i16 int16
var i32 int32
// 암시적 형변환
i32 = i16
// 명시적 형변환
i32 = int32(i16)
type MyInt int
var i int
var j MyInt
func main() {
i = 3
j = 1 // 컴파일 에러
j = MyInt(i) // 반드시 명시적 형변환 필요
...
}
* goroutine
goroutine 은 매번 커널 스레드를 생성하지 않고, 일부 커널 스레드로 멀티플렉싱되어 사용된다. goroutine 마다 하나의 스레드를 점유하는 방식이 아니라 동작하는 goroutine 이 멀티플렉스를 이용해 스레드에 할당되는 방식.
func doSomeThing() {
...
}
func main() {
go doSomeThing()
}
* 채널(channel)
두 goroutine 이 공유할 데이터가 있는 경우 채널을 통해 상대 goroutine 으로 데이터를 전달할 수 있다.
func main() {
c := make(chan int)
go func() {
...
c<-1 // 채널 c 로 1 를 보낸다.
}()
<-c // 채널 c 에서 값을 받아 사용하지 않고 버린다.
fmt.Print("main End");
}
// 단항 연산자로 사용된 <- (receive)
v = <-c // 채널 c 에서 값을 받아서 v 에 대입한다
i := <- c // 채널 c 에서 값을 받고 이 값으로 i 를 초기화한다
※ 한빛미디어에서 나온 팝업북 형식의 "개발자를 위한 하룻밤에 읽는 Go 언어 이야기" (신제용 저) 읽고 나서 Go 언어에 관심이 더 생기게 되었다. 전자책 출판용으로 작성된 글이다 보니 코드 부분에서 오류가 조금 있고 설명이 대충 넘어가는 듯한 부분이 있어서 아쉽지만, 그래도 그동안 Go 언어를 대충 함수형 언어로만 생각하고 다음에 찾아보지 생각했었는데 이 책을 통해 Go 언어의 시작이 어떠했는지, 어떠한 용도로 나왔는지를 알 수 있는 책이었다.
'Engineering > Etc' 카테고리의 다른 글
사업자 현황 신고_소형주택 (0) | 2020.02.10 |
---|---|
링크를 gmail 을 통해 mail 로 전달하는 chrome extension (0) | 2019.11.04 |
객체지향 개발 5대 원리 : SOLID (0) | 2019.09.27 |
MsgPack 을 이용해서 직접 write 구현하기 (0) | 2018.11.22 |
Sublime Text 에서 ColorPicker 가 동작하지 않을 때 해결 방법 (0) | 2018.11.01 |