go 문법
import 문법
import "fmt" 또는 import ( "fmt" "math" )
함수선언
func add(x int, y int) int { return x + y } 또는 func add(x, y int) int { return x + y } 여러개 return func add(x, y int) (int, int) { return x, y } return 에 이름 붙이기(알아서 x, y 가 return 됨) func add(x, y int) (x, y int) { x = x + 1 y = y + 1 return } // func(int) int 를 return 하는 함수 adder() func adder() func(int) int { sum := 0 return func(x int) int { sum += x return sum } }
변수선언
const ( cc1 = "hello" cc2 = "babo" ) var x, y, z int var a, b, c int = 1, 2, 3 var p, j bool var k, l = true, "no" type Pointer struct { X, Y int } func main() { aa, bb := true, "hello!" // 함수내에서만 가능 const gogolang = "gogo" fmt.Println(a, b, c, x, y, z, p, j) // 배열, slice 라 부른다. p := []int{2, 3, 5, 7, 11, 13} fmt.Println(p[0]) fmt.Println("p[1:4] ==", p[1:4]) fmt.Println("p[:3] ==", p[:3]) fmt.Println("p[4:] ==", p[4:]) // 배열 생성, '0' 으로 초기화된다. arr := make([]int, 5) // len(arr)=5, array item 은 int type arr2 := make([]int, 0, 5) // len(b)=0, cap(b)=5 , 용량제한 // // var m map[string]Pointer m = make(map[string]Pointer) m["1stPointer"] = Pointer{ 0, 1} fmt.Println(m["1stPointer"]) // // var mm = map[string]Pointer{ "1stP": Pointer{0,1}, "2ndP": {2,3}, } // m2 := make(map[string]int) m2["mykey"] = 48 delete(m2, "mykey") v, ok := m2["mykey"] // mykey 가 존재하면 ok 는 true, 존재하지 않으면 ok 는 false } }
slice 참고 자료
make 함수
type Job func() jobQueue := make(chan Job, 10) // buffer 가 10 인 channel 만들기 jobQueue := make([]Job, 10) // Job 10개가 들어가는 array 만들기 r := make(<-chan bool) // 읽기 전용 채널 w := make(chan<- []os.FileInfo) // 쓰기 전용 채널 // a channel which: // - you can only write to // - holds another channel as its value c := make(chan<- chan bool) // 아래 "channel 관련" 을 참고하자.
slice / map /chan 을 new 할때 쓴다. slice, map, chan 에 사용할 때, 각각 다른 방식으로 동작한다.
이 녀석이 allocate 하고, initialize 를 해준다. 참고로, 이 make 를 써야하는 slice/map/chan 은 선언(declare) 만 해서는 reference 만 생성된다. 그러니 struct 안에넣을 때는 make() 를 호출 해주는 init 함수등이 따로 필요하다.
channel
ready := make(chan bool)
위와 같은 unbuffered channel은 sender 나 receiver 가 준비가 돼서 communicate 가 될 때까지 block 된다. 그러므로, 이 녀석은 필연적으로 goroutine 과 함께 써야 한다. 왜냐하면, 만약 이 channel 에 대해 read 를 시도하면, 일단 block 되어 버리는데, 이상태에서 이 channel 에 write 를 해줄 방법은 goroutine 등 다른 thread 를 사용하는 수밖에 없기 때문이다.
cap()
len() 은 data 가 얼마나 존재하는지 알려주고, cap() 이라는 것은 array 가 있으면 이 array 가 할당해 놓은 memory size 를 이야기한다.nil
None, null 같은 개념이다.error type
type error interface { Error() string }
errors.New 로 error type 의 string 을 만들 수 있다.
func Sqrt(f float64) (float64, error) { if f < 0 { return 0, errors.New("math: square root of negative number") } // implementation }
for 문
sum := 0
for i := 0; i < 10; i++ {
sum += i
}
//
j := 0
for j < 10 {
sum += j
}
//
for{
if j < 10 {
sum += j
}
}
//
var arr = []int{1, 2, 4, 8, 16, 32, 64, 128}
func main() {
for i, v := range arr {
fmt.Printf("2**%d = %d\n", i, v)
}
for _, v := range arr {
fmt.Printf(v)
}
for i := range arr {
fmt.Printf(i)
}
}
if, switch 문
if j:= math.Pow(1,2); j < 100 { fmt.Println(j) }else{ // j는 if, else 안에서만 사용 fmt.Println(j) } import "runtime" switch os := runtime.GOOS; os { case "darwin": fmt.Println("OS X.") // break 가 없어도 자동으로 break 된다. case os + "_X": fmt.Println("Linux.") default: fmt.Printf("%s.", os) } // if--then--else 대용으로 사용하면 된다. t := time.Now() switch { // switch true case t.Hour() < 12: fmt.Println("Good morning!") case t.Hour() < 17: fmt.Println("Good afternoon.") default: fmt.Println("Good evening.") }
기본 자료형
bool string int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 uintptr byte // uint8의 다른 이름(alias) rune // int32의 다른 이름(alias) // 유니코드 코드 포인트 값을 표현합니다. float32 float64 complex64 complex128
string 참고 소스
구조체 struct
type Point struct {
X int
Y int
}
var (
p = Pointer{1, 2} // has type Vertex
q = &Pointer{1, 2} // has type *Vertex
r = Pointer{X: 1} // Y:0 is implicit
s = Pointer{} // X:0 and Y:0
)
func main() {
p := Point{1, 2} // create
p.X = 4
q := &p // pointer 할당
q.X = 5
fmt.Println(p.Y)
fmt.Println(q.X) // q.X 는 5 가 되고, p.X 도 5가 된다.
//
v := new(Pionter) // new 는 필드를 '0' 으로 초기화 한다.
v.X = 5
var w *Pointer = new(Pointer) // w:= new(Pointer)
w.X = 10
}
go 는 pointer 가 있지만, pointer 연산은 안된다.
class 문법
class 는 없고, struct 에 함수를 추가할 수 있다.(결국 이름 붙이기 나름이긴 하다. ) 여하튼 이때 pointer type 과 일반적인 type 으로 method receiver 를 설정할 수 있다. 자세한 것은 여기를 참고하자.
// modified while the server is running. type Server struct { running bool } // Peers returns all connected peers. func (srv *Server) Peers() []*Peer { var ps []*Peer select { // Note: We'd love to put this function into a variable but // that seems to cause a weird compiler error in some // environments. case srv.peerOp <- func(peers map[discover.NodeID]*Peer) { for _, p := range peers { ps = append(ps, p) } }: <-srv.peerOpDone case <-srv.quit: } return ps } // // 기존 type 에 함수를 추가, 기본 type 에는 추가할 수 없지만, 아래처럼 새롭게 자신의 type 을 선언하면 된다. // 그리고 다른 package 에 있는 type 에 추가할 수는 없다. // type MyFloat float64 func (f MyFloat) Abs() float64 { if f < 0 { return float64(-f) } return float64(f) } func main() { f := MyFloat(-math.Sqrt2) fmt.Println(f.Abs()) }
strconv
string --> inti, err := strconv.Atoi("-42") s := strconv.Itoa(-42)
interface
변수선언할 때 interface{} type 은 Java 의 object처럼 가장 상위 개념의 type 이라 봐도 좋을 듯 하다.
interface type 으로 variable 을 하나 선언하면,
이 variable 로 모든 interface type 을 받을 수 있고, primitive type 도 받을 수 있기 때문이다.
func main() {
var i interface{} = 3.0
s := i.(float64)
fmt.Println(s)
s, ok := i.(float64)
fmt.Println(s, ok)
f, ok := i.(string)
fmt.Println(f, ok)
f = i.(string) // panic
fmt.Println(f)
}
import "strconv" type Stringer interface { ToString() string } func main() { var a Stringer f := MyFloat(103.22) v := Vertex{3.0, 4.0} a = f // a MyFloat implements Stringer a = &v // a *Vertex implements Stringer a = v // Error: a Vertex, does NOT implement Stringer fmt.Println(a.Abs()) } // MyFloat type MyFloat float64 func (f MyFloat) ToString() string { return strconv.FormatFloat(f, 'f', -1, 64) // infinite precision '-1' , 64 bit } // Vertex type Vertex struct { X, Y float64 } func (v *Vertex) ToString() string { return strconv.Itoa(v.X) }
type assertions
이 때 이 interface 가 가진 child 에 따라 동작을 하도록 하려면, 아래처럼 (type) 과 switch 를 이용할 수 있다.type Stringer interface { String() string } var value interface{} // Value provided by caller. switch str := value.(type) { case string: return str case Stringer: return str.String() }
function pointer
함수를 parameter 로 넘기는 것은 간단하다.func paramFunc(title string) int{ fmt.Println(title) return 1 } func testFuncPointer(fn func(string) int) int{ ret := fn("test") return ret } func main() { testFuncPointer(paramFunc) }
file i/o
import "io/ioutil" var body = []byte("Test") ioutil.WriteFile(filename, body, 0600) // 0600 is permission body, error := ioutil.ReadFile(filename)
defer
이 녀석은 python 의 with 같다. java 의 fianlly 와도 비슷하다. 근데 약간 이름이 부자연스럽긴 하다.아래 코드에서 defer 는 function 이 끝나는 시점에 수행된다. 즉, writeFile 을 하고 난 후에 closeFile 이 실행된다.
func main() { f := createFile("/tmp/defer.txt") defer closeFile(f) writeFile(f) }
thread
go 에서는 goroutine 으로 불린다. go 뒤에 수행하고 싶은 function 을 넣으면 된다. 그러면 go func 을 한 순간부터 run 이 되는 것이다.go func(){ fmt.Println("this is a thread")}
select
대략적으로 이야기하면, queue 에서 값을 가져와서 어떤 작업을 하는 녀석(예를 들면, dispatcher) 을 만들 때 사용하면 된다.(좀 더 응용해서 어떤 신호를 받을 때 사용하면 된다.)select 가 만약 default 를 가지고 있으면, queue 가 empty 일때 default 가 호출된다. 그리고 default 가 없다면, queue 에 item 이 들어올 때 까지 block 된다.(참고)
type Job func() type worker struct { jobChannel chan Job } func (w *worker) start() { // new thread start go func() { var job Job for { select { case job = <-w.jobChannel: job() } } }() }
예제
package main
import (
"fmt"
"os"
"bufio"
"strings"
"strconv"
)
func main() {
fmt.Println("Hello, 世界")
var caseCount, cPlank int
fmt.Scanf("%d\n", &caseCount)
for i := 0; i<caseCount; i++{
var hlist []int32
fmt.Scanf("%d\n", &cPlank)
reader := bufio.NewReader(os.Stdin)
fmt.Print("Enter text: ")
text, _ := reader.ReadString('\n')
text = strings.TrimRight(text, "\r\n")
// convert string to []int
// "3 2 4" --> [3, 2, 4]
splitStr := strings.Split(text, " ")
for _, s := range splitStr{
pint, err := strconv.ParseInt(s, 10, 64)
if err != nil{
fmt.Print("error")
fmt.Println(err)
}
hlist = append(hlist, int32(pint))
}
fmt.Println(hlist)
}
}
See Also
- A Tour of Go
- Go by Example
- avelino/awesome-go: A curated list of awesome Go frameworks, libraries and software
- Projects · golang/go Wiki
- Learn Go by writing tests – Hello, world : https://github.com/quii/learn-go-with-tests/tree/master/hello-world
댓글 없음:
댓글 쓰기