Golang - 네가 모르는 10가지
13342 단어 Go
10 things you (probably) don’t know about golang
익명 구조(Anonymous structs)
템플릿 데이터
data := struct {
Title string
Users []*User // User ,
} {
title,
USERS,
}
err := tmpl.Execute(w, data)
(Cheaper and safer than using map [string]interface {})가 확실히 이해가 안 되네요. 무슨 뜻이죠?
내장형 잠금(Embedded Lock)
var hits struct{
sync.Mutex // ,( )
n int
}
hits.Lock() // ( C++ )
hits.n++
hits.Unlock()
Nested structs 내포된 구조
Decoding deeply nested JSON data
{"data" : {"children" : [
{"data" : {
"title" : "The Go homepage",
"url" : "http://golang.org/"}}
,
...
]}}
type Item struct{
Titel string
URL string
}
type Response struct{ // Structs Json ,
Data struct {
Children []struct {
Data Item
}
}
}
golang json , JSON 。
Command-line godoc 명령행 godoc
% godoc sync Mutex // godoc ,sync , Mutex
디스플레이 값은 다음과 같습니다.
type Mutex struct { //contains filtered or unexported fields } A Mutex is a mutual exclusion lock. Mutexes can be created as part of other structures; the zero value for a Mutex is an unlocked mutex.
func (m *Mutex) Lock() Lock locks m. If the lock is already in use, the calling goroutine blocks until the mutex is available.
func (m *Mutex) Unlock() Unlock unlocks m. It is a run-time error if m is not locked on entry to Unlock.
A locked Mutex is not associated with a particular goroutine. It is
allowed for one goroutine to lock a Mutex and then arrange for another
goroutine to unlock it.
godc -src는 Golang의 소스 코드를 직접 표시할 수 있습니다.
% godoc -src sync Mutex
다음과 같이 표시됩니다.
//A Mutex is a mutual exclusion lock.//Mutexes can be created as part of other structures//the zero value for a Mutex is an unlocked mutex. type Mutex struct { state int32 sema uint32 }//Local per-P Pool appendix. type poolLocal struct { Mutex//Protects shared. //contains filtered or unexported fields }
보시면 unexported state가 표시됩니다!우리가 원본 코드에 대해 깊이 있는 탐색을 진행하는 데 편리하다.
Mock out the file system(파일 시스템 패러디)
현재 패키지가 있습니다. 이 패키지는 파일 시스템과 협업을 해야 합니다. 하지만 테스트에 진정한 디스크를 사용하고 싶지 않습니다. 어떻게 해야 합니까?
var fs fileSystem = osFS{}
type fileSystem interface { //
Open(name string) (file, error)
Stat(name string) (os.fileInfo, error)
}
type file interface { // file
io.Closer
io.Reader
io.ReaderAt
io.Seeker
Stat() (os.FileInfo, error)
}
type osFs struct{} // osFs , fileSystem 。
func (osFs) Open(name string) (file, error) // , file
func (osFs) Stat(name string) (os.FileInfo, error)
Method expression
type T struct{} // T
func (T) Foo(string) {fmt.Println(s)} // T
//fn ,
// : fn func(T, string)
// Foo : func (T) Foo(string)
var fn func(T, sring) = T.Foo
os/exec의 실제 예:
func (c *Cmd) stdin() (f *os.File, error)
func (c *Cmd) stdout() (f *os.File, error)
func (c *Cmd) stderr() (f *os.File, error)
type F func(*cmd) (*os.File, error)
for _, setupFd := range []F{(*Cmd).stdin, (*Cmd).stdout, (*Cmd).stderr} { //
fd, err := steupFd(c)
if err != nil {
c.closeDescriptors(c.closeAfterStart)
c.closeDescriptors(c.closeAfterWait)
return err
}
c.childFiles = append(c.childFiles, fd)
}
Send and receive on the same channel
package main
import "fmt"
var battle = make(chan string) // channel
func warrior(name string, done chan struct{}) {
// : select , channel ?
select {
case oppoent := //battle
fmt.Printf("%s beat %s
", name, oppoent)
case battle //battle
// I lost
}
done struct{}{}
}
func main() {
done := make(chan struct{})
langs := []string{"Go", "C", "C++", "Java", "Perl", "Python"}
for _, s := range langs {
go warrior(s, done) // Goroutine
}
for _ = range langs {
// Goroutine , ?
}
}
프로그램이 여러 번 실행되고 출력이 같지 않습니다: 처음 실행:
Java beat C++ Go beat C Perl beat Python
두 번째 실행:
Python beat Perl Go beat C C++ beat Java
지금 문제는: 1.같은 Select에서 두 개 혹은 두 개 이상의case 문장에서 같은 채널이 데이터를 수신하면 어떻게 됩니까?2. 같은 채널이 동시에 데이터를 보내면 어떻게 될까?3. 같은 채널(발송과 수신) 데이터는 어떻게 되나요?자발적으로 수확하는 현상이 있을까요?
자신의 추측: 1.만약 두 개의 채널이 동시에 데이터를 발송한다면 랜덤으로 하나의 채널을 선택하여 데이터를 발송할 것이다.만약 두 개의 채널이 동시에 데이터를 수신한다면, 랜덤으로 하나의 채널을 선택하여 데이터를 수신할 것이다.3. 같은 채널(발송과 수신) 데이터는 자발적인 수신 현상을 일으키지 않고 이 채널에 막힌다.상술한 예에 대해 구체적인 Select는 어떻게 일을 하는지 잘 모르겠다.(고수의 가르침을 구함)
Close로 브로드캐스트하는 Using close to broadcast
package main
import (
"fmt"
"math/rand" //
"time"
)
func waiter(i int, block, done chan struct{}) {
time.Sleep(time.Duration(rand.Intn(3000)) * time.Millisecond)
fmt.Println(i, "waiting...")
// goroutine block , close(block)
fmt.Println(i, "done!")
done struct{}{}
}
func main() {
block, done := make(chan struct{}), make(chan struct{})
for i := 0; i < 4; i++ {
go waiter(i, block, done)
}
time.Sleep(5 * time.Second)
close(block) // , block ( )
for i := 0; i < 4; i++ {
3 waiting...
2 waiting...
1 waiting...
0 waiting...
3 done!
2 done!
1 done!
0 done!
NIl channel in select
func worker(i int, ch chan work, quit chan struct{}) {
for {
select {
case w :=if quit == nil { // channel == nil ?
w.Refuse();
fmt.Println("worker", i, "refused",w)
break;
}
w.Do();
case "worker", i, "quiting")
quit = nil ( nil)
}
}
}
func main() {
ch, quit := make(chan work), make(chan struct{})
go makeWork(ch)
for i := 0; i < 4; i++ {
go worker(i, ch, quit)
}
time.Sleep(5 * time.Second)
close(quit)
time.Sleep(2 * time.Second)
}
상술한 코드는 약간 잘 모르는 부분이 있다.1.close(quit)가 되면,quit는 정상적인 채널에서nil로 바뀌나요?(아닐 것이다) 2.만약 quit가 돌아오지 않았을 때, 노동자는 영원히 일을 하고 있을 것이다.3. Qit가 돌아오면 Qit=nil, 그리고 그 다음에 일꾼에게 일을 명령하려면 일꾼은 물러나 그만둔다.
총결산
전체적으로 어려운 점은 채널과 struct에 있다.1. 채널의 다양한 이용으로 동기화와 비동기화, 병발 등의 기능을 실현한다.코드에서만 탐색할 수 있습니다.2. 골롱의 메모리 모델에 대해 잘 이해하지 못하고 많은 부분이 불분명하다.나중에 천천히 이해할 수밖에 없어요.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Golang과 DB를 연결하여 주가 데이터를 그래프로 표시합니다.진화 제작된 프로그램. 지난번에 한 품종에 집중되어 데이터를 보였는데, 이번에는 텍스트 상자에 입력한 품종 코드를 바탕으로 나는 도표를 표시하는 기능을 만들고 싶다. html에서 텍스트 상자와 단추를 준비하세요. w...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.