go 1.5 발표

go lang 2015. 6. 3. 00:44



http://talks.golang.org/2015/gogo.slide#1



1.5 전 버전에는 go 내부 구조는 c로 개발되었으나, 1.5는 모두 언어의 내부 시스템을 go로 구현했다고 했다. 또한 다양한 기능이 추가되었다. 


Big changes

All made easier by owning the tools and/or moving to Go:

  • linker rearchitecture
  • new garbage collector
  • stack maps
  • contiguous stacks
  • write barriers

The last three are all but impossible in C:

  • C is not type safe; don't always know what's a pointer
  • aliasing of stack slots caused by optimization

(Gccgo will have segmented stacks and imprecise (stack) collection for a while yet.)



'go lang' 카테고리의 다른 글

[go] 멀티라인 (다중 라인)  (0) 2017.08.29
[golang] Go 공부 시작 링크  (0) 2017.08.29
godeps 예제  (0) 2015.04.02
[go lang] command option 받기  (0) 2015.03.28
[go lang] import 별명 (alias)  (0) 2015.03.28
Posted by '김용환'
,

godeps 예제

go lang 2015. 4. 2. 01:05



https://github.com/ddliu/go-httpclient 를 이용한 go 샘플 예제로 godep를 사용해보았다. 



<설치>

1. godep 설치

설치된 godep은 $GOPATH/bin에 설치된다. 

2. path 추가
~/.bash_profile에 다음을 추가

export PATH=$PATH:$GOPATH:$GOPATH/bin
 

설정 reload
$ source ~/.bash_profile



3. 정상 실행 확인
$ godep

Godep is a tool for managing Go package dependencies.

Usage:

godep command [arguments]

The commands are:

save list and copy dependencies into Godeps
go run the go tool with saved dependencies
get download and install packages with specified dependencies
path print GOPATH for dependency code
restore check out listed dependency versions in GOPATH
update use different revision of selected packages

Use "godep help [command]" for more information about a command.




<테스트>

go의 httpclient 설치

$ go get github.com/ddliu/go-httpclient



$ cd src/github.com/knight76/godep


새로운 프로젝트에 github.com/knight76/godep 를 생성하고 main.go 작성한다. 

package main

import "github.com/ddliu/go-httpclient"

func main() {
httpclient.Defaults(httpclient.Map{
httpclient.OPT_USERAGENT: "googlebot",
"Accept-Language": "kr",
})

res, err := httpclient.Get("http://google.com/search", map[string]string{
"q": "news",
})

println(res.StatusCode, err)
}



godep 디렉토리에 Godeps 이 추가되지 않는다면, bin/godep 삭제하고 src/github.com/tools/godep도 삭제한다. 다시 go get github.com/tools/godep 을 입력해서 다시 다운로드한다.


$ godep save 하면 아래와 같이 Godeps/Godeps.json 파일이 생성된다. godep save의 내용은 dependency를 생성한다.

$ cat Godeps.json
{
"ImportPath": "github.com/knight76/godep",
"GoVersion": "go1.4.2",
"Deps": [
{
"ImportPath": "github.com/ddliu/go-httpclient",
"Comment": "v0.5.0-1-gc94e588",
"Rev": "c94e588d6261421924e2fd042ffba9cf7054f62a"
}
]
}



참고로 type godep는 다음과 같다.
type Godeps struct {
    ImportPath string
    GoVersion  string   // Abridged output of 'go version'.
    Packages   []string // Arguments to godep save, if any.
    Deps       []struct {
        ImportPath string
        Comment    string // Description of commit, if present.
        Rev        string // VCS-specific commit ID.
    }
}




dependency lib가 새로 변경되면, 다음을 실행한다.


$ go get -u github.com/ddliu/go-httpclient




실행 파일을 생성하기 위해서는 godep go build를 생성한다.

$ godep go build
$ ls  godep
godep
$ ./godep
(실행결과)


저장된 depencenty lib를 이용해서 빌드하기 위해서는 godep go install을 실행한다.

$ godep go install





참고내용
https://gowalker.org/github.com/tools/godep
https://flynn.io/docs/how-to-deploy-go
https://github.com/tools/godep
http://blog.gopheracademy.com/advent-2014/deps/




Posted by '김용환'
,


command option 받는 방법


1. golang 기본 패키지인 flag를 사용하기


http://golang.org/pkg/flag/



package main


import (

"flag"

"fmt"

)


func main() {

var param int

flag.IntVar(&param, "param", 1, "param value")

flag.Parse()


fmt.Printf("param = %d\n", param)

}




결과 

$ go run src/test/test.go --param=100

param = 100

$ go run src/test/test.go 

param = 1



2. 


https://github.com/handlename/go-opts


$ go get github.com/handlename/go-opts


package main


import (

"fmt"


"github.com/handlename/go-opts"

)


type Options struct {

Name string `flag:"name" default:"김용환" description:"이름"`

Age  int    `flag:"age" default:"20" description:"나이"`

}


func main() {

options := Options{}

opts.Parse(&options)

fmt.Println(options)

}


결과

$ go run src/test/test.go --name="이두근" --age=10

{이두근 10}

$ go run src/test/test.go

{김용환 20}





package main


import (

"fmt"


"github.com/handlename/go-opts"

)


type Options struct {

Name string `flag:"param" default:"1" description:"param value"`

}


func main() {

options := Options{}

opts.Parse(&options)

fmt.Println(options)

}



$ go run src/test/test_1.go --param=3

{3}


Posted by '김용환'
,

다음 3개의 결과는 모두 동일하다.

go lang은 import 패키지를 가르키는 식별자를 변경할 수 있다. 


1) 식별자를 따로 주지 않은 경우 (일반적인 케이스)

package main


import (

"fmt"

"math"

)


func main() {

fmt.Println(math.Abs(-11))

}


2) 식별자를 주지 않는 경우 - 'import .' 을 사용
(java의 import static과 비슷)

package main

import (
"fmt"
. "math"
)

func main() {
fmt.Println(Abs(-11))
}


2) 패키지 식별자를 따로 준 경우 - 'import 별명'을 사용

package main


import (

"fmt"

MATH "math"

)


func main() {

fmt.Println(MATH.Abs(-11))

}





Posted by '김용환'
,



만약 go lang에서 not used library를 사용시에는 go 컴파일 에러가 발생한다 

 imported and not used: "fmt"


또는 사용하지 않은 변수를 선언해도 에러가 발생하고 실행이 되지 않는다. 


package main


import "fmt"


func main() {

var z int

var m map[string]int

m = map[string]int{}

m["a"] = 1

m["b"] = 2


for i, j := range m {

fmt.Printf("%s %d\n", i, j)

}

}



# command-line-arguments
src/test/test.go:6: z declared and not used
[Finished in 0.061s]



사용하지 않는 변수들은 정리하면 되는데,


특이한 경우는 아래와 같은 경우인데, for 문에서 range 의 iterator를 쓰지 않을 때에도 에러가 발생한다.


func main() {

x := [2]int{1, 2}


var total int = 0

for i, value := range x {

total += value

}

fmt.Println(total / int(len(x)))

}


# command-line-arguments
src/test/test.go:9: i declared and not used
[Finished in 0.043s]



따라서, 이런 코드는 i 라는 변수를 쓰지 않겠다는 의미로, underscope(_)를 사용한다.


func main() {

x := [2]int{1, 2}


var total int = 0

for _, value := range x {

total += value

}

fmt.Println(total / int(len(x)))

}



Posted by '김용환'
,


예제 코드를 찾아서 복사하다가 갑지기 panic 컴파일 오류를 만날 수 있다. 

panic: assignment to entry in nil map



package main


import "fmt"


func main() {

var m map[string]int

m["a"] = 1

m["b"] = 2


for i, j := range m {

fmt.Printf("%s %d\n", i, j)

}

}



그 이유는 map을 초기화하지 않은 상태(nil)에서 값을 할당(assignment)하다가  발생한 것이다. 



panic: assignment to entry in nil map


goroutine 1 [running]:

main.main()

/mydev/go/src/test/test.go:8 +0x76


goroutine 2 [runnable]:

runtime.forcegchelper()

/usr/local/go/src/runtime/proc.go:90

runtime.goexit()

/usr/local/go/src/runtime/asm_amd64.s:2232 +0x1


goroutine 3 [runnable]:

runtime.bgsweep()

/usr/local/go/src/runtime/mgc0.go:82

runtime.goexit()

/usr/local/go/src/runtime/asm_amd64.s:2232 +0x1


goroutine 4 [runnable]:

runtime.runfinq()

/usr/local/go/src/runtime/malloc.go:712

runtime.goexit()

/usr/local/go/src/runtime/asm_amd64.s:2232 +0x1

exit status 2

[Finished in 0.146s]




이럴 때는 map을 초기화해야 한다. 

package main


import "fmt"


func main() {

var m map[string]int

m = map[string]int{}

m["a"] = 1

m["b"] = 2


for i, j := range m {

fmt.Printf("%s %d\n", i, j)

}

}




문제 해결된다. 

Posted by '김용환'
,


scala의 underscore(_)의 특징이 go lang에도 있는 것 같다. 나는 스칼라의 underscore를 '거시기'로 생각했다.

http://stackoverflow.com/questions/8000903/what-are-all-the-uses-of-an-underscore-in-scala


go에도 비슷한 의미로 사용하려고 한 것 같다.  아직까지는 많이 발견하지 못했지만.. 찾게 되면 계속 작성해야 겠다. 



_(underscore)의 사용이 for에도 적용된다. 


1) key 를 사용하지 않겠다는 의미가 있다.

package main


import "fmt"


func main() {

var m map[string]int 

        m = map[string]int{}

m["a"] = 1

m["b"] = 2

sum := 0

for _, value := range m {

sum += value

}

fmt.Println(sum)

}


출력

3



2) 값을 대입받는 의미로도 쓰인다. 


ackage main


import "fmt"


func main() {

var m map[string]int

m = map[string]int{}

m["a"] = 1

m["b"] = 2


for i, _ := range m {

fmt.Println(i)

}

}



결과

a

b


여기서는 아래의 코드와 동일한 효과가 있다. 


for i := range m {

fmt.Println(i)

}




3) import시 dependency lib는 사용하지 않는 용도로 쓰인다. 


the Go Specification

To import a package solely for its side-effects (initialization), use the blank identifier as explicit package name:

import _ "lib/math"



참고로 underscore는 값의 개념(value)로 쓸 수 없다.

cannot use _ as value


Posted by '김용환'
,


출처 : https://atom.io/packages/script


[MAC OS기준]


atom에서 Setting-View-install 에서 install package에서 script를 선택하고 다운로드






command + i 누르면 바로 go run을 해볼 수 있음.

(go run화면 밑에 go-plus는 http://knight76.tistory.com/entry/Go-Lang-Atom-%EC%97%90%EC%84%9C-Go-Lang-%ED%99%98%EA%B2%BD-%EC%84%A4%EC%A0%95%ED%95%98%EA%B8%B0 을 참조




* Short Key 설명


command + i : 실행

command + cmd + j : 옵션 지정

ctrl + w ( 또는 esc) : go run 결과창 닫기 (command + w는 소스 창을 닫는 것)

ctrl + c : 종료 (무한 루프 빠질 때 사용)






Posted by '김용환'
,



https://github.com/fogleman/nes 

이 곳에 NES ROM 에뮬레이터가 존재한다. go 언어 소스도 보고 어떻게 동작하는지 보려고 테스트해보았다.

바로 다운받으면 머큐리얼 클라이언트인 hg가 없다고 발생한다. 

$ go get github.com/fogleman/nes

go: missing Mercurial command. See http://golang.org/s/gogetcmd

package code.google.com/p/portaudio-go/portaudio: exec: "hg": executable file not found in $PATH



그래서, http://mercurial.selenic.com/ 에서 hg 다운로드받고 $PATH에 등록한다.

그 다음 dependency를 다운받는다.  (godeps가 왜 의미가 있는지 알게 된다.)


$ go get github.com/go-gl/gl/v2.1/gl 

$ go get github.com/go-gl/glfw/v3.1/glfw 

$ go get code.google.com/p/portaudio-go/portaudio 

# pkg-config --cflags portaudio-2.0

Package portaudio-2.0 was not found in the pkg-config search path. 

Perhaps you should add the directory containing `portaudio-2.0.pc' 

to the PKG_CONFIG_PATH environment variable 

No package 'portaudio-2.0' found 



portaudio이 패키지 패스에 없어서 소스 컴파일해서 pkgconfig path에 복사해보았지만.. 동작되지 않았다.


(이 방법은 쓰면 안되었음)

http://www.portaudio.com/download.html 에서 tgz 다운로드 (pa_stable_v19_20140130.tgz  최신 버전 )

http://portaudio.com/docs/v19-doxydocs/compile_mac_coreaudio.html 보고 따라하기

$ ./configure && make

portaudio-2.0.pc 생성

$ sudo cp portaudio-2.0.pc /usr/lib/pkgconfig/



그래서 brew를 이용하니 동작되었다.


brew install portaudio

sudo brew link portaudio



계속 진행해서 nes를 GOPATH에 만들게 했다. 

$ go get code.google.com/p/portaudio-go/portaudio 

$ go get github.com/fogleman/nes

$ which nes

/mydev/go/bin/nes



어렸을 때 했던 버블버블 nes rom 하나를 다운받아 실행해 보았다. 


$ /mydev/go/bin/nes BubbleBobble.nes



그리고, 소스에 눈이 가게 된다. ..

https://github.com/fogleman/nes 

Posted by '김용환'
,


Atom에서 go 언어 개발할 수 있도록 셋팅하기 위해 go-plus를 사용한다.

https://github.com/joefitzgerald/go-plus

(아직 완벽하지는 않지만, 아주 쓸만하다.)



1. 도구 설치

$ go get code.google.com/p/go.tools/cmd/goimports

$ go get github.com/golang/lint/golint



2. Atom에서 go-plus패키지 설치


Atom의 메뉴, Packages 에서 Settings View ---> 

Install Package/Theme 를 선택


입력칸에 go-plus 입력하고 검색한다.


(기본적인 환경 설정인 GOPATH, GOLANG 이 되어야 한다.설정이 안되어 있다면, 설정 변경후, atom 재실행한다.)



3. Atom에서 go-plus의 Settings 변경

Command + , (settings)로 이동한후, packages 선택 후, 설치된 go-plus의 settings설정 변경




입력 란에 GO 설치된 내용을 저장 한다.  


Go excutable Path : /usr/local/go/bin/go

Go path : $GOPATH


설정 내용을 보면, IDE툴의 내용이 있다. 대부분 check on 되어 있다. 


소스를 두고, 테스트를 해본다. 하단의 go-plus 창에 "String"이라는 undefined 문자에 대한 에러를 보여준다. 



실제 테스트를 해보면 동일하게 나타난다.



$ go run src/test/test.go

# command-line-arguments

src/test/test.go:6: undefined: String



정상적으로 수정하면 더 이상 컴파일 에러는 발생하지 않는다. 



$ go run src/test/test.go

2


Posted by '김용환'
,