Tidak banyak kode Go untuk dipelajari, dan saya yakin saya bukan satu-satunya yang bereksperimen dengannya. Jadi, jika Anda menemukan sesuatu yang menarik tentang bahasa tersebut, silakan kirim contohnya di sini.
Dukungan ARM seperti 8-bit atau 16-bit. Bahasa D masih belum.
1
Perpustakaan ( golang.org/pkg ) adalah sumber yang sangat baik untuk mempelajari bagaimana go digunakan. Secara pribadi, saya menemukan bahwa mempelajari bagaimana struktur data diimplementasikan sangat membantu untuk mempelajari bahasa.
tkokasih
Jawaban:
35
Tunda pernyataan
Pernyataan "defer" memanggil fungsi yang eksekusinya ditangguhkan saat fungsi di sekitarnya kembali.
DeferStmt = Ekspresi "menunda".
Ekspresi tersebut harus berupa pemanggilan fungsi atau metode. Setiap kali pernyataan "defer" dijalankan, parameter ke pemanggilan fungsi dievaluasi dan disimpan lagi tetapi fungsi tersebut tidak dipanggil. Panggilan fungsi yang ditangguhkan dijalankan dalam urutan LIFO segera sebelum fungsi sekitarnya kembali, tetapi setelah nilai yang dikembalikan, jika ada, telah dievaluasi.
lock(l);
defer unlock(l); // unlocking happens before surrounding function returns// prints 3 2 1 0 before surrounding function returnsfor i := 0; i <= 3; i++ {
defer fmt.Print(i);
}
Memperbarui:
defersekarang juga merupakan cara idiomatik untuk menangani panicdengan cara seperti pengecualian :
package main
import"fmt"funcmain() {
f()
fmt.Println("Returned normally from f.")
}
funcf() {
deferfunc() {
if r := recover(); r != nil {
fmt.Println("Recovered in f", r)
}
}()
fmt.Println("Calling g.")
g(0)
fmt.Println("Returned normally from g.")
}
funcg(i int) {
if i > 3 {
fmt.Println("Panicking!")
panic(fmt.Sprintf("%v", i))
}
defer fmt.Println("Defer in g", i)
fmt.Println("Printing in g", i)
g(i+1)
}
Sepertinya RAII lama yang bagus (dibuat eksplisit).
Konrad Rudolph
4
+1 karena saya banyak membaca tentang Go, tetapi saya masih tidak melihat ini (sampai Anda menunjukkannya kepada saya)!
u0b34a0f6ae
Pintar, meskipun akan lebih masuk akal bagi saya jika menunda pernyataan yang dieksekusi dalam urutan FIFO (dari atas ke bawah), tapi mungkin itu hanya saya ...
@ Mike: jika Anda membandingkan dengan blok "coba: .. akhirnya:" LIFO bersarang dengan cara yang sama. Untuk pasangan buka / tutup sumber daya dll, menumpuk seperti ini adalah satu-satunya hal yang masuk akal (Pembukaan pertama akan ditutup terakhir).
u0b34a0f6ae
25
File objek Go sebenarnya menyertakan header cleartext:
jurily@jurily ~/workspace/go/euler31 $ 6g euler31.go
jurily@jurily ~/workspace/go/euler31 $ cat euler31.6
amd64
exports automatically generated from
euler31.go in package"main"import
$$ // exportspackage main
var main.coin [9]intfuncmain.howmany(amount int, max int)(? int)funcmain.main()var main.initdone· uint8funcmain.init()
$$ // local typestype main.dsigddd_1·1struct { ? int }
$$
!
<binary segment>
Itu lebih seperti fitur tersembunyi daripada contoh idiomatik
hasen
22
Saya telah melihat beberapa orang mengeluh tentang loop-for, di sepanjang baris "mengapa kita harus mengatakan i = 0; i < len; i++di zaman sekarang ini?".
Saya tidak setuju, saya suka untuk konstruksi. Anda dapat menggunakan versi panjang jika Anda mau, tetapi idiomatis Go adalah
var a = []int{1, 2, 3}
for i, v := range a {
fmt.Println(i, v)
}
The for .. rangemembangun loop atas semua elemen dan persediaan dua nilai - indeks idan nilai v.
range juga berfungsi pada peta dan saluran.
Namun, jika Anda tidak suka fordalam bentuk apa pun, Anda dapat menentukan each, mapdll. Dalam beberapa baris:
type IntArr []int// 'each' takes a function argument.// The function must accept two ints, the index and value,// and will be called on each element in turn.func(a IntArr)each(fn func(index, value int)) {
for i, v := range a {
fn(i, v)
}
}
funcmain() {
var a = IntArr([]int{2, 0, 0, 9}) // create int slice and cast to IntArrvar fnPrint = func(i, v int) {
fmt.Println(i, ":", v)
} // create a function
a.each(fnPrint) // call on each element
}
Saya tidak yakin apa yang seharusnya salah dengan pemformatan; Saya telah memulihkannya.
5
Penulis Go merekomendasikan ke gofmtkode Anda :-)
ℝaphink
Saya tidak dapat mengkompilasinya: $ ../go/src/cmd/6g/6g SO.go SO.go: 34: undefined: json.StringToJson
ℝaphink
@Raphink: bahasanya telah berubah sejak saya membuat ini.
Ya, apakah Anda tahu mungkin apa yang paling mirip dengan StringToJson? Dulu menyiapkan pembangun secara internal, sekarang seseorang harus menyediakan sendiri dengan struktur asli yang telah ditentukan?
type ByteSize float64const (
_ = iota; // ignore first value by assigning to blank identifier
KB ByteSize = 1<<(10*iota)
MB
GB
TB
PB
YB
)
// This implicitly repeats to fill in all the values (!)
switch {
case'0' <= c && c <= '9':
return c - '0'case'a' <= c && c <= 'f':
return c - 'a' + 10case'A' <= c && c <= 'F':
return c - 'A' + 10
}
return0
Pernyataan switch menjadi true ketika tidak ada ekspresi yang diberikan. Jadi ini setara dengan
if'0' <= c && c <= '9' {
return c - '0'
} elseif'a' <= c && c <= 'f' {
return c - 'a' + 10
} elseif'A' <= c && c <= 'F' {
return c - 'A' + 10
}
return0
Saat ini, versi sakelar tampak sedikit lebih bersih bagi saya.
switch i := x.(type) {
casenil:
printString("x is nil");
caseint:
printInt(i); // i is an intcase float:
printFloat(i); // i is a floatcasefunc(int)float:
printFunction(i); // i is a functioncasebool, string:
printString("type is bool or string"); // i is an interface{}default:
printString("don't know the type");
}
Kembali atau hasil "parameter" dari fungsi Go dapat diberi nama dan digunakan sebagai variabel biasa, seperti parameter yang masuk. Ketika dinamai, mereka diinisialisasi ke nilai nol untuk tipenya saat fungsi dimulai; jika fungsi menjalankan pernyataan pengembalian tanpa argumen, nilai saat ini dari parameter hasil digunakan sebagai nilai yang dikembalikan.
Nama tidak wajib tetapi dapat membuat kode lebih pendek dan lebih jelas: ini adalah dokumentasi. Jika kita menamai hasil nextInt maka menjadi jelas mana yang dikembalikan int adalah yang mana.
Karena hasil yang diberi nama diinisialisasi dan dikaitkan dengan pengembalian tanpa hiasan, hasil tersebut dapat menyederhanakan dan juga memperjelas. Ini adalah versi io.ReadFull yang menggunakannya dengan baik:
/*
* How many different ways can £2 be made using any number of coins?
* Now with 100% less semicolons!
*/package main
import"fmt"/* This line took me over 10 minutes to figure out.
* "[...]" means "figure out the size yourself"
* If you only specify "[]", it will try to create a slice, which is a reference to an existing array.
* Also, ":=" doesn't work here.
*/var coin = [...]int{0, 1, 2, 5, 10, 20, 50, 100, 200}
funchowmany(amount int, max int)int {
if amount == 0 { return1 }
if amount < 0 { return0 }
if max <= 0 && amount >= 1 { return0 }
// recursion works as expectedreturn howmany(amount, max-1) + howmany(amount-coin[max], max)
}
funcmain() {
fmt.Println(howmany(200, len(coin)-1))
}
Saya sarankan menghapus nama situs pemecahan masalah serta nomor id. Mungkin ulangi pertanyaannya. Agar tidak merusak masalah kepada seseorang yang tersandung olehnya. Atau mencoba menipu dengan mencari masalah di internet.
Saya suka Anda dapat mendefinisikan ulang tipe, termasuk primitif seperti int, sebanyak yang Anda suka dan melampirkan metode yang berbeda. Seperti mendefinisikan tipe RomanNumeral:
package main
import (
"fmt""strings"
)
var numText = "zero one two three four five six seven eight nine ten"var numRoman = "- I II III IV V VI VII IX X"var aText = strings.Split(numText, " ")
var aRoman = strings.Split(numRoman, " ")
type TextNumber inttype RomanNumber intfunc(n TextNumber)String()string {
return aText[n]
}
func(n RomanNumber)String()string {
return aRoman[n]
}
funcmain() {
var i = 5
fmt.Println("Number: ", i, TextNumber(i), RomanNumber(i))
}
Yang mencetak
Number: 5 five V
The RomanNumber()panggilan dasarnya gips, itu mengubah jenis int sebagai jenis yang lebih spesifik dari int. Dan Println()panggilan di String()belakang layar.
Ini adalah idiom sejati yang cukup penting: bagaimana memasukkan data ke dalam saluran dan menutupnya setelahnya. Dengan ini Anda dapat membuat iterator sederhana (karena range akan menerima saluran) atau filter.
// return a channel that doubles the values in the input channelfuncDoublingIterator(input chanint)chanint {
outch := make(chanint);
// start a goroutine to feed the channel (asynchronously)gofunc() {
for x := range input {
outch <- 2*x;
}
// close the channel we created and controlclose(outch);
}();
return outch;
}
+1. Selain itu, Anda juga dapat melewatkan saluran melalui saluran.
György Andrasek
5
Tapi hati-hati agar tidak keluar dari loop for x: = range chan {}, Anda akan membocorkan goroutine, dan semua memori yang direferensikannya.
Jeff Allen
3
@JeffAllen bagaimana defer close(outch);dengan pernyataan pertama dari goroutine?
1
Tunda antrian pernyataan untuk dieksekusi ketika fungsi kembali, tidak peduli titik pengembalian mana yang diambil. Tetapi jika input saluran tidak pernah ditutup, maka fungsi anonim dalam contoh ini tidak akan pernah meninggalkan loop for.
Jeff Allen
11
Batas waktu untuk pembacaan saluran:
ticker := time.NewTicker(ns);
select {
case v := <- chan_target:
do_something_with_v;
case <- ticker.C:
handle_timeout;
}
Ada pengaturan sistem make yang dapat Anda gunakan di $ GOROOT / src
Siapkan makefile Anda dengan
TARG=foobar # Name of package to compile
GOFILES=foo.go bar.go # Go sources
CGOFILES=bang.cgo # Sources to run cgo on
OFILES=a_c_file.$O # Sources compiled with $Oc
# $O is the arch number (6for x86_64)
include $(GOROOT)/src/Make.$(GOARCH)
include $(GOROOT)/src/Make.pkg
Anda kemudian dapat menggunakan alat pengujian otomatis dengan menjalankan make test, atau menambahkan paket dan objek bersama dari cgo ke $ GOROOT Anda dengan make install.
Ini adalah implementasi dari tumpukan. Ini mengilustrasikan menambahkan metode ke sebuah tipe.
Saya ingin membuat bagian tumpukannya menjadi irisan dan menggunakan properti irisan, tetapi meskipun saya membuatnya bekerja tanpa type, saya tidak dapat melihat sintaks untuk menentukan irisan dengan a type.
package main
import"fmt"import"os"const stack_max = 100type Stack2 struct {
stack [stack_max]string
size int
}
func(s *Stack2)push(pushed_string string) {
n := s.size
if n >= stack_max-1 {
fmt.Print("Oh noes\n")
os.Exit(1)
}
s.size++
s.stack[n] = pushed_string
}
func(s *Stack2)pop()string {
n := s.size
if n == 0 {
fmt.Print("Underflow\n")
os.Exit(1)
}
top := s.stack[n-1]
s.size--
return top
}
func(s *Stack2)print_all() {
n := s.size
fmt.Printf("Stack size is %d\n", n)
for i := 0; i < n; i++ {
fmt.Printf("%d:\t%s\n", i, s.stack[i])
}
}
funcmain() {
stack := new(Stack2)
stack.print_all()
stack.push("boo")
stack.print_all()
popped := stack.pop()
fmt.Printf("Stack top is %s\n", popped)
stack.print_all()
stack.push("moo")
stack.push("zoo")
stack.print_all()
popped2 := stack.pop()
fmt.Printf("Stack top is %s\n", popped2)
stack.print_all()
}
Daripada menggunakan fmt.Printf(...); os.Exit();, Anda bisa menggunakan panic(...).
notnoop
1
Itu memberikan jejak tumpukan, yang tidak saya inginkan.
3
Mengapa dibatasi? Go adalah bahasa terkelola dan gc'd. Tumpukan Anda bisa sedalam yang Anda inginkan. Gunakan append () builtin yang baru, yang akan melakukan sesuatu seperti realokasi C jika diperlukan.
Jeff Allen
"Pergi tidak perlu obat generik", kata mereka.
cubuspl42
4
Memanggil kode c dari go
Anda dapat mengakses tingkat perjalanan yang lebih rendah dengan menggunakan runtime c.
Fungsi C ada dalam bentuk
void package·function(...)
(perhatikan pemisah titik adalah karakter unicode) di mana argumen dapat berupa tipe dasar go, irisan, string, dll. Untuk mengembalikan panggilan nilai
FLUSH(&ret)
(Anda dapat mengembalikan lebih dari satu nilai)
Misalnya untuk membuat sebuah fungsi
package foo
bar( a int32, b string )(c float32 ){
c = 1.3 + float32(a - int32(len(b))
}
di C yang Anda gunakan
#include "runtime.h"
void foo·bar(int32 a, String b, float32 c){
c = 1.3 + a - b.len;
FLUSH(&c);
}
Perhatikan bahwa Anda masih harus mendeklarasikan fungsi dalam file go, dan Anda harus menjaga memorinya sendiri. Saya tidak yakin apakah mungkin untuk memanggil pustaka eksternal menggunakan ini, mungkin lebih baik menggunakan cgo.
Lihat $ GOROOT / src / pkg / runtime untuk contoh yang digunakan dalam runtime.
Lihat juga jawaban ini untuk menghubungkan kode c ++ dengan go.
Benarkah itu menggunakan "titik terbang"? Saya tidak berani mengedit, tapi sepertinya agak tidak terduga dan radikal.
bersantai
Ya, Anda perlu mengkompilasi dengan 6c (atau 8c, dll). Menurut saya gcc tidak menangani pengenal unicode.
Scott Wales
1
Saya pikir AltGr + tipe periode yang sama · tetapi dengan unicode saya tidak yakin. Sangat terkejut melihat bahwa di sumber yang saya baca .. mengapa tidak menggunakan sesuatu seperti ::?
u0b34a0f6ae
Karakternya adalah MIDDLE DOT U + 00B7. Pengurai mungkin telah dipalsukan sehingga melihat ini sebagai karakter untuk membuat pengenal c yang valid, yang saya percaya akan menghalangi ::.
Scott Wales
4
'·' Hanyalah peretasan sementara, rob bahkan terkejut bahwa itu masih ada, katanya akan diganti dengan sesuatu yang tidak terlalu aneh.
uriel
4
Berikut adalah contoh go menggunakan paket sqlite3.
Tentu saja. Persis seperti itulah yang terjadi di sini. Saya hanya suka foreverkata kuncinya. Bahkan Qt memiliki makro untuk itu.
György Andrasek
6
tapi Go tidak membutuhkan makro atau alias lucu untuk melakukan ini.
u0b34a0f6ae
@ kaizer.se: Poin Jurily adalah bahwa for ever(setelah mendeklarasikan variabel) adalah sesuatu yang lucu yang dapat Anda lakukan di Go jika Anda mau. Sepertinya bahasa Inggris (modulo kosong).
Frank
8
itu adalah sesuatu yang lucu yang dapat Anda lakukan di C juga .. :-)#define ever (;;)
u0b34a0f6ae
2
Ada banyak program kecil di testdirektori utama. Contoh:
Jawaban:
Tunda pernyataan
lock(l); defer unlock(l); // unlocking happens before surrounding function returns // prints 3 2 1 0 before surrounding function returns for i := 0; i <= 3; i++ { defer fmt.Print(i); }
Memperbarui:
defer
sekarang juga merupakan cara idiomatik untuk menanganipanic
dengan cara seperti pengecualian :package main import "fmt" func main() { f() fmt.Println("Returned normally from f.") } func f() { defer func() { if r := recover(); r != nil { fmt.Println("Recovered in f", r) } }() fmt.Println("Calling g.") g(0) fmt.Println("Returned normally from g.") } func g(i int) { if i > 3 { fmt.Println("Panicking!") panic(fmt.Sprintf("%v", i)) } defer fmt.Println("Defer in g", i) fmt.Println("Printing in g", i) g(i+1) }
sumber
File objek Go sebenarnya menyertakan header cleartext:
jurily@jurily ~/workspace/go/euler31 $ 6g euler31.go jurily@jurily ~/workspace/go/euler31 $ cat euler31.6 amd64 exports automatically generated from euler31.go in package "main" import $$ // exports package main var main.coin [9]int func main.howmany (amount int, max int) (? int) func main.main () var main.initdone· uint8 func main.init () $$ // local types type main.dsigddd_1·1 struct { ? int } $$ ! <binary segment>
sumber
Saya telah melihat beberapa orang mengeluh tentang loop-for, di sepanjang baris "mengapa kita harus mengatakan
i = 0; i < len; i++
di zaman sekarang ini?".Saya tidak setuju, saya suka untuk konstruksi. Anda dapat menggunakan versi panjang jika Anda mau, tetapi idiomatis Go adalah
var a = []int{1, 2, 3} for i, v := range a { fmt.Println(i, v) }
The
for .. range
membangun loop atas semua elemen dan persediaan dua nilai - indeksi
dan nilaiv
.range
juga berfungsi pada peta dan saluran.Namun, jika Anda tidak suka
for
dalam bentuk apa pun, Anda dapat menentukaneach
,map
dll. Dalam beberapa baris:type IntArr []int // 'each' takes a function argument. // The function must accept two ints, the index and value, // and will be called on each element in turn. func (a IntArr) each(fn func(index, value int)) { for i, v := range a { fn(i, v) } } func main() { var a = IntArr([]int{2, 0, 0, 9}) // create int slice and cast to IntArr var fnPrint = func(i, v int) { fmt.Println(i, ":", v) } // create a function a.each(fnPrint) // call on each element }
cetakan
0 : 2 1 : 0 2 : 0 3 : 9
Saya mulai sangat menyukai Go :)
sumber
range
hanya bagus, jika dikompilasi ke kode yang sama dengan loop for-3.Pergi dan dapatkan reputasi stackoverflow Anda
Ini adalah terjemahan dari jawaban ini .
package main import ( "json" "fmt" "http" "os" "strings" ) func die(message string) { fmt.Printf("%s.\n", message); os.Exit(1); } func main() { kinopiko_flair := "https://stackoverflow.com/users/flair/181548.json" response, _, err := http.Get(kinopiko_flair) if err != nil { die(fmt.Sprintf("Error getting %s", kinopiko_flair)) } var nr int const buf_size = 0x1000 buf := make([]byte, buf_size) nr, err = response.Body.Read(buf) if err != nil && error != os.EOF { die(fmt.Sprintf("Error reading response: %s", err.String())) } if nr >= buf_size { die ("Buffer overrun") } response.Body.Close() json_text := strings.Split(string(buf), "\000", 2) parsed, ok, errtok := json.StringToJson(json_text[0]) if ! ok { die(fmt.Sprintf("Error parsing JSON %s at %s", json_text, errtok)) } fmt.Printf("Your stackoverflow.com reputation is %s\n", parsed.Get ("reputation")) }
Terima kasih kepada Scott Wales atas bantuannya dengan .Read ().
Ini masih terlihat cukup kikuk, dengan dua string dan dua buffer, jadi jika ada pakar Go yang memiliki saran, beri tahu saya.
sumber
gofmt
kode Anda :-)Inilah contoh bagus iota dari pos Kinopiko :
type ByteSize float64 const ( _ = iota; // ignore first value by assigning to blank identifier KB ByteSize = 1<<(10*iota) MB GB TB PB YB ) // This implicitly repeats to fill in all the values (!)
sumber
Anda dapat menukar variabel dengan tugas paralel:
x, y = y, x // or in an array a[j], a[i] = a[i], a[j]
sederhana tetapi efektif.
sumber
Berikut ini adalah idiom dari Efektif Go halaman
switch { case '0' <= c && c <= '9': return c - '0' case 'a' <= c && c <= 'f': return c - 'a' + 10 case 'A' <= c && c <= 'F': return c - 'A' + 10 } return 0
Pernyataan switch menjadi true ketika tidak ada ekspresi yang diberikan. Jadi ini setara dengan
if '0' <= c && c <= '9' { return c - '0' } else if 'a' <= c && c <= 'f' { return c - 'a' + 10 } else if 'A' <= c && c <= 'F' { return c - 'A' + 10 } return 0
Saat ini, versi sakelar tampak sedikit lebih bersih bagi saya.
sumber
Switch True
…)Jenis sakelar :
switch i := x.(type) { case nil: printString("x is nil"); case int: printInt(i); // i is an int case float: printFloat(i); // i is a float case func(int) float: printFunction(i); // i is a function case bool, string: printString("type is bool or string"); // i is an interface{} default: printString("don't know the type"); }
sumber
Saat mengimpor paket, Anda dapat menentukan ulang namanya menjadi apa pun yang Anda inginkan:
package main import f "fmt" func main() { f.Printf("Hello World\n") }
sumber
Parameter hasil bernama
func nextInt(b []byte, pos int) (value, nextPos int) {
func ReadFull(r Reader, buf []byte) (n int, err os.Error) { for len(buf) > 0 && err == nil { var nr int; nr, err = r.Read(buf); n += nr; buf = buf[nr:len(buf)]; } return; }
sumber
Dari jawaban James Antill :
foo := <-ch // This blocks. foo, ok := <-ch // This returns immediately.
Juga, potensi jebakan: perbedaan halus antara operator penerima dan pengirim:
a <- ch // sends ch to channel a <-ch // reads from channel ch
sumber
/* * How many different ways can £2 be made using any number of coins? * Now with 100% less semicolons! */ package main import "fmt" /* This line took me over 10 minutes to figure out. * "[...]" means "figure out the size yourself" * If you only specify "[]", it will try to create a slice, which is a reference to an existing array. * Also, ":=" doesn't work here. */ var coin = [...]int{0, 1, 2, 5, 10, 20, 50, 100, 200} func howmany(amount int, max int) int { if amount == 0 { return 1 } if amount < 0 { return 0 } if max <= 0 && amount >= 1 { return 0 } // recursion works as expected return howmany(amount, max-1) + howmany(amount-coin[max], max) } func main() { fmt.Println(howmany(200, len(coin)-1)) }
sumber
Saya suka Anda dapat mendefinisikan ulang tipe, termasuk primitif seperti int, sebanyak yang Anda suka dan melampirkan metode yang berbeda. Seperti mendefinisikan tipe RomanNumeral:
package main import ( "fmt" "strings" ) var numText = "zero one two three four five six seven eight nine ten" var numRoman = "- I II III IV V VI VII IX X" var aText = strings.Split(numText, " ") var aRoman = strings.Split(numRoman, " ") type TextNumber int type RomanNumber int func (n TextNumber) String() string { return aText[n] } func (n RomanNumber) String() string { return aRoman[n] } func main() { var i = 5 fmt.Println("Number: ", i, TextNumber(i), RomanNumber(i)) }
Yang mencetak
Number: 5 five V
The
RomanNumber()
panggilan dasarnya gips, itu mengubah jenis int sebagai jenis yang lebih spesifik dari int. DanPrintln()
panggilan diString()
belakang layar.sumber
Mengembalikan saluran
Ini adalah idiom sejati yang cukup penting: bagaimana memasukkan data ke dalam saluran dan menutupnya setelahnya. Dengan ini Anda dapat membuat iterator sederhana (karena range akan menerima saluran) atau filter.
// return a channel that doubles the values in the input channel func DoublingIterator(input chan int) chan int { outch := make(chan int); // start a goroutine to feed the channel (asynchronously) go func() { for x := range input { outch <- 2*x; } // close the channel we created and control close(outch); }(); return outch; }
sumber
defer close(outch);
dengan pernyataan pertama dari goroutine?Batas waktu untuk pembacaan saluran:
ticker := time.NewTicker(ns); select { case v := <- chan_target: do_something_with_v; case <- ticker.C: handle_timeout; }
Dicuri dari Davies Liu .
sumber
for { v := <-ch if closed(ch) { break } fmt.Println(v) }
Karena range secara otomatis memeriksa saluran tertutup, kita dapat mempersingkatnya menjadi ini:
for v := range ch { fmt.Println(v) }
sumber
Ada pengaturan sistem make yang dapat Anda gunakan di $ GOROOT / src
Siapkan makefile Anda dengan
TARG=foobar # Name of package to compile GOFILES=foo.go bar.go # Go sources CGOFILES=bang.cgo # Sources to run cgo on OFILES=a_c_file.$O # Sources compiled with $Oc # $O is the arch number (6 for x86_64) include $(GOROOT)/src/Make.$(GOARCH) include $(GOROOT)/src/Make.pkg
Anda kemudian dapat menggunakan alat pengujian otomatis dengan menjalankan make test, atau menambahkan paket dan objek bersama dari cgo ke $ GOROOT Anda dengan make install.
sumber
Hal menarik lainnya di Go adalah itu
godoc
. Anda dapat menjalankannya sebagai server web di komputer Anda menggunakangodoc -http=:8080
di mana 8080 adalah nomor port, dan seluruh situs web di golang.org kemudian tersedia di
localhost:8080
.sumber
Ini adalah implementasi dari tumpukan. Ini mengilustrasikan menambahkan metode ke sebuah tipe.
Saya ingin membuat bagian tumpukannya menjadi irisan dan menggunakan properti irisan, tetapi meskipun saya membuatnya bekerja tanpa
type
, saya tidak dapat melihat sintaks untuk menentukan irisan dengan atype
.package main import "fmt" import "os" const stack_max = 100 type Stack2 struct { stack [stack_max]string size int } func (s *Stack2) push(pushed_string string) { n := s.size if n >= stack_max-1 { fmt.Print("Oh noes\n") os.Exit(1) } s.size++ s.stack[n] = pushed_string } func (s *Stack2) pop() string { n := s.size if n == 0 { fmt.Print("Underflow\n") os.Exit(1) } top := s.stack[n-1] s.size-- return top } func (s *Stack2) print_all() { n := s.size fmt.Printf("Stack size is %d\n", n) for i := 0; i < n; i++ { fmt.Printf("%d:\t%s\n", i, s.stack[i]) } } func main() { stack := new(Stack2) stack.print_all() stack.push("boo") stack.print_all() popped := stack.pop() fmt.Printf("Stack top is %s\n", popped) stack.print_all() stack.push("moo") stack.push("zoo") stack.print_all() popped2 := stack.pop() fmt.Printf("Stack top is %s\n", popped2) stack.print_all() }
sumber
fmt.Printf(...); os.Exit();
, Anda bisa menggunakanpanic(...)
.Memanggil kode c dari go
Anda dapat mengakses tingkat perjalanan yang lebih rendah dengan menggunakan runtime c.
Fungsi C ada dalam bentuk
void package·function(...)
(perhatikan pemisah titik adalah karakter unicode) di mana argumen dapat berupa tipe dasar go, irisan, string, dll. Untuk mengembalikan panggilan nilai
(Anda dapat mengembalikan lebih dari satu nilai)
Misalnya untuk membuat sebuah fungsi
package foo bar( a int32, b string )(c float32 ){ c = 1.3 + float32(a - int32(len(b)) }
di C yang Anda gunakan
#include "runtime.h" void foo·bar(int32 a, String b, float32 c){ c = 1.3 + a - b.len; FLUSH(&c); }
Perhatikan bahwa Anda masih harus mendeklarasikan fungsi dalam file go, dan Anda harus menjaga memorinya sendiri. Saya tidak yakin apakah mungkin untuk memanggil pustaka eksternal menggunakan ini, mungkin lebih baik menggunakan cgo.
Lihat $ GOROOT / src / pkg / runtime untuk contoh yang digunakan dalam runtime.
Lihat juga jawaban ini untuk menghubungkan kode c ++ dengan go.
sumber
Berikut adalah contoh go menggunakan paket sqlite3.
http://github.com/bikal/gosqlite-example
sumber
Apakah Anda menonton pembicaraan ini ? Ini menunjukkan banyak hal keren yang dapat Anda lakukan (akhir pembicaraan)
sumber
Tumpukan berdasarkan jawaban lain, tetapi menggunakan penambahan irisan tidak memiliki batas ukuran.
package main import "fmt" import "os" type Stack2 struct { // initial storage space for the stack stack [10]string cur []string } func (s *Stack2) push(pushed_string string) { s.cur = append(s.cur, pushed_string) } func (s *Stack2) pop() (popped string) { if len(s.cur) == 0 { fmt.Print("Underflow\n") os.Exit(1) } popped = s.cur[len(s.cur)-1] s.cur = s.cur[0 : len(s.cur)-1] return } func (s *Stack2) print_all() { fmt.Printf("Stack size is %d\n", len(s.cur)) for i, s := range s.cur { fmt.Printf("%d:\t%s\n", i, s) } } func NewStack() (stack *Stack2) { stack = new(Stack2) // init the slice to an empty slice of the underlying storage stack.cur = stack.stack[0:0] return } func main() { stack := NewStack() stack.print_all() stack.push("boo") stack.print_all() popped := stack.pop() fmt.Printf("Stack top is %s\n", popped) stack.print_all() stack.push("moo") stack.push("zoo") stack.print_all() popped2 := stack.pop() fmt.Printf("Stack top is %s\n", popped2) stack.print_all() }
sumber
const ever = true for ever { // infinite loop }
sumber
for { /* infinite loop */ }
cukup.forever
kata kuncinya. Bahkan Qt memiliki makro untuk itu.for ever
(setelah mendeklarasikan variabel) adalah sesuatu yang lucu yang dapat Anda lakukan di Go jika Anda mau. Sepertinya bahasa Inggris (modulo kosong).#define ever (;;)
Ada banyak program kecil di
test
direktori utama. Contoh:peano.go
mencetak faktorial.hilbert.go
memiliki beberapa perkalian matriks.iota.go
memiliki contoh hal iota yang aneh.sumber