The Go Programming Language -앨런 도노반, 브라이언 커니건
2021. 6. 6. 11:16ㆍBooks/Programmers
728x90
반응형
Hello, World
package main
import "fmt"
func main() {
fmt.Println("Hello, World")
}
- 작은 기본 구성 요소들을 모아 큰 프로그램을 만든다
- 25개의 키워드가 있다.
- 낙타 표기법(Camel case)을 사용한다. 밑줄 보다는 대문자를 더 선호
- 선언에는 주로 var, const, type, func의 네 가지 종류가 있다.
변수
- var 선언은 특정 타입의 변수를 만들고 이름을 붙인 뒤 초기 값을 설정
- 값을 갖는 저장소
- var 이름 타입 = 표현식
- 이름 := 표현식
// var 이름 타입 = 표현식
var s string
fmt.Println(s)
// 이름 := 표현식
freq := rand.Float64() * 3.0
t := 0.0
- 변수의 수명
- 변수의 수명은 프로그램이 실행될 때 변수가 존재하는 시간의 길이다
- 패키지 수준 변수의 수명은 프로그램 전체 실행 기간과 동일
- 지역 변수의 수명은 동적
- 선언문이 실행될 때마다 새 인스턴스 생성
포인터
- 변수의 주소, 포인터는 값이 저장돼 있는 위치
- 변수의 주소를 취하거나 복사할 때마다 변수의 새 별명이나 동일한 변수를 식별할 수 있는 새로운 방법을 만든다
- 변수에 접근 하려면 변수의 모든 별명까지 알아야 한다
//
x := 1 // 변수
p := &x // 포인터 선언
*p = 2 // 주소 접근
new 함수
- new(T) 표현식은 타입의 이름 없는 변수를 만들고 포인터 값인 변수의 주소를 반환한다
x := new(int) // *int 타입 x는 이름 없는 int 변수를 가리킨다
fmt.Println(*p) // "0"
할당성
- 함수 호출은 인자 값들을 그에 대응하는 파라미터들에 묵시적으로 할당
- return 문은 return 문의 피연산자에 대응하는 반환
- 할당문은 명시적이든 묵시적이든 왼쪽(변수)와 오른쪽(값)의 타입이 같으면 적법하다
배열
- 0개 이상의 특정 타입 원소로 이뤄진 고정 길이 시퀀스
- 고정 길이이기 때문에 직접 사용하는 경우가 거의 없다
슬라이스
- 모든 원소가 같은 타입인 가변 길이 시퀀스
- []T로 쓴다, 크기가 없는 배열 타입
- 포인터, 길이, 용량 세 가지 구성 요소
- 배열과 달리 비교할 수 없다
var s []int
len(s) == 0 // 슬라이스가 비어 있는지 확인
//
var s = make([]int, 3)
// append, 슬라이스에 항목을 추가
var runes []rune
runes = append(runes, "3")
//// 결과
[3]
맵
- 순서 없는 키/값 쌍의 모음
- 모든 키는 별개이며 주어진 키와 관련된 값은 해시 테이블의 크기와 무관하게 평균적으로 일정한 회수의 키 비교를 통해 추출, 갱신, 제거할 수 있다
- 맵은 해시 테이블의 참조
- map[Key]Value
- graph
var graph = make(map[string]map[string]bool)
func addEdge(from, to string){
edges := graph[from]
if edges == nil{
edges = make(map[string]bool)
graph[from] = edges
}
edges[to] = true
}
func hasEdge(from, to string) bool{
return graph[from][to]
}
구조체
- 구조체는 0개 이상의 명명된 임의의 타입 값을 하나의 개체로 모으는 집합형 데이터 타입
- 각 값은 필드라 한다.
- 개체 단위로 복사, 함수 전달, 반환, 배열에 저장 등 할 수 있다.
- 구조체 리터럴
// 명확한 순서가 있는 구조체에 명시
type Point struct{ X, Y int}
p := Point{1, 2}
// 필드가 연관되는 값 목록으로 초기화
type VertexStruct struct{ X, Y int }
mv := make(map[string]VertexStruct)
mv["v1"] = VertexStruct{X: 10, Y: 20}
fmt.Println(mv["v1"])
JSON
- 자바스크립트 객체 표기법
- 자바스크립트 값을 유니코드 텍스트로 인코딩한 것
- 마샬링, Data 구조 → json
// 데이터 구조를 JSON으로 변환
type Movie struct{
Title string
Year int `json:"released"`
Color bool `json:"color,omitempty"`
Actors []string
}
var movies = []Movie{
{Title: "Casab", Year: 1942, Color: false, Actors: []string{"A","B"},
{Title: "Casab2", Year: 1952, Color: false, Actors: []string{"C","B"},
}
//data, err := json.Marshal(movies)
data, err := json.MarshalIndent(movies, "", " ") // 좀 더 깔끔하게 들여쓰기 한 결과 제공
if err != nil{
log.Fatalf("JSON error marshaling : %s", err)
}
fmt.Printf("%s\n", data)
defer
- 연기된 함수
func sum(vals ...int) int{
total := 0
for _, val := range vals{
total += val
}
fmt.Println(sum)
return total
}
defer sum(1,2,3)
sum(1,2,3,4,5)
//// 결과
15
6
인터페이스
- 다른 타입의 동작을 일반화 하거나 추상화해서 표현
- 함수를 특정 구현의 세부 사항에 구애받지 않고 더 유연하고 융통성 있게 작성 가능
- 인터페이스 타입은 구상 타입이 해당 인터페이스의 인스턴스로 인식되기 위해 필요한 메소드들을 지정
- 종종 인터페이스의 집합부터 만들고 나중에 인터페이스를 충족하는 구상 타입을 정의
- 인터페이스는 두 개 이상의 타입을 충족할 때에만 사용되므로 특정 구현을 추상화 하기 위해 반드시 필요
type MyFloat float64
type Vertex struct {
X, Y float64
}
type Abser interface {
Abs() float64
}
func (f MyFloat) Abs() float64 {
if f < 0 {
return float64(-f)
}
return float64(f)
}
func (v *Vertex) Abs() float64 {
return math.Sqrt(v.X*v.X + v.Y*v.Y)
}
var a Abser
f := MyFloat(-math.Sqrt2)
v := Vertex{3, 4}
a = f
fmt.Println(a.Abs()) // a MyFloat implements
a = &v
fmt.Println(a.Abs()) // a *Vertex implements
// a = v // dose not implement Abser!
//// 결과
1.4142135623730951
5
고루틴
- 독립적인 작업(goroutine)간에 값을 전달
- 동시에 수행되는 작업
//
func say(s string) {
for i := 0; i < 5; i++ {
time.Sleep(100 * time.Millisecond)
fmt.Println(s)
}
}
go say("world")
say("hello")
//// 결과
hello
world
hello
world
hello
world
world
hello
hello
채널
- 고루틴 간의 연결
- 한 고루틴이 다른 고루틴으로 값을 보내기 위한 통신 메커니즘
- 채널을 복사하거나 함수의 인자로 전달할 때, 참조를 복사, 호출자와 피호출자는 같은 데이터 구조를 참조
- ch ← x //송신 구문
x = ← ch // 할당문 안의 수신 표현식
← ch //수신 구문, 결과는 버려짐
- ch ← x //송신 구문
func sum(s []int, c chan int) {
sum := 0
for _, v := range s {
sum += v
}
c <- sum // send sum to c
}
s := []int{7, 2, 8, -9, 4, 0}
c := make(chan int)
go sum(s[:len(s)/2], c)
go sum(s[len(s)/2:], c)
x, y := <-c, <-c // receive from c
fmt.Println(x, y, x+y)
//// 결과
-5 17 12
- close는 이 채널에 더 이상 값을 보내지 않음을 나타내는 플래그
- close(ch)
- 수신된 채널 요소 및 보통 ok로 부르며 수신에 성공하면 true, 닫혔거나 소진된 채널에서 수신하면 false를 반환
728x90
반응형
'Books > Programmers' 카테고리의 다른 글
Terraform Up & Running - 예브게니 브릭만 (0) | 2021.05.25 |
---|---|
그림으로 배우는 서버구조 - 니시무라 야스히로 (0) | 2021.05.16 |
개발자의 글쓰기 - 김철수 (0) | 2021.03.24 |
Programmers 책03 (0) | 2017.02.15 |
Programmers 책 02 (0) | 2017.02.11 |