ไปดูตัวอย่างและสำนวน [ปิด]


91

ไม่มีรหัส Go ให้เรียนรู้ภาษามากนักและฉันแน่ใจว่าไม่ใช่คนเดียวที่ทดลองใช้ ดังนั้นหากคุณพบสิ่งที่น่าสนใจเกี่ยวกับภาษาโปรดโพสต์ตัวอย่างที่นี่

ฉันยังมองหา

  • วิธีการทำสิ่งต่างๆใน Go
  • รูปแบบการคิด C / C ++ "พอร์ต" ไปที่ Go,
  • ข้อผิดพลาดทั่วไปเกี่ยวกับไวยากรณ์
  • อะไรที่น่าสนใจจริงๆ

รองรับ ARM เช่น 8 บิตหรือ 16 บิต ภาษา D ยังคงทำไม่ได้

1
ห้องสมุด ( golang.org/pkg ) เป็นแหล่งข้อมูลที่ดีเยี่ยมในการเรียนรู้วิธีใช้ go โดยส่วนตัวแล้วฉันพบว่าการเรียนรู้วิธีการนำโครงสร้างข้อมูลไปใช้นั้นมีประโยชน์ในการเรียนรู้ภาษา
tkokasih

คำตอบ:


35

เลื่อนคำสั่ง

คำสั่ง "defer" เรียกใช้ฟังก์ชันที่การดำเนินการถูกเลื่อนออกไปในขณะที่ฟังก์ชันโดยรอบส่งกลับ

DeferStmt = นิพจน์ "defer"

นิพจน์ต้องเป็นการเรียกใช้ฟังก์ชันหรือเมธอด ทุกครั้งที่คำสั่ง "defer" ดำเนินการพารามิเตอร์ที่เรียกใช้ฟังก์ชันจะได้รับการประเมินและบันทึกใหม่ แต่จะไม่มีการเรียกใช้ฟังก์ชัน การเรียกใช้ฟังก์ชันรอการตัดบัญชีจะดำเนินการตามลำดับ LIFO ทันทีก่อนที่ฟังก์ชันรอบข้างจะส่งคืน แต่หลังจากค่าที่ส่งคืนถ้ามีจะได้รับการประเมิน


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);
}

อัปเดต:

deferตอนนี้ยังเป็นวิธีการจัดการpanicในลักษณะที่เหมือนข้อยกเว้น :

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)
}

17
ดูเหมือน RAII รุ่นเก่าที่ดี (ทำให้ชัดเจน)
Konrad Rudolph

4
+1 เนื่องจากฉันอ่านเกี่ยวกับ Go มามาก แต่ฉันก็ยังไม่เห็นสิ่งนี้ (จนกว่าคุณจะแสดงให้ฉันเห็น)!
u0b34a0f6ae

ฉลาดแม้ว่ามันจะสมเหตุสมผลกว่าสำหรับฉันหากเลื่อนคำสั่งที่ดำเนินการในคำสั่ง FIFO (บนลงล่าง) แต่นั่นอาจเป็นแค่ฉัน ...
Mike Spross

เย็น. ทำให้ฉันนึกถึง scrop guards จาก D digitalmars.com/d/2.0/exception-safe.html
hasen

4
@ ไมค์: ถ้าคุณเปรียบเทียบกับบล็อกของ "ลอง: .. ในที่สุด:" LIFO รังในลักษณะเดียวกัน สำหรับคู่ทรัพยากรเปิด / ปิด ฯลฯ การซ้อนกันเช่นนี้เป็นสิ่งเดียวที่สมเหตุสมผล (เปิดครั้งแรกจะปิดสุดท้าย)
u0b34a0f6ae

25

ไปที่ไฟล์ออบเจ็กต์มีส่วนหัวที่ชัดเจน

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>

6
นั่นเป็นเหมือนคุณสมบัติที่ซ่อนอยู่มากกว่าตัวอย่างสำนวน
hasen

22

ฉันเคยเห็นคนสองสามคนบ่นเรื่อง for-loop ตลอดแนวว่า "ทำไมเราต้องพูดi = 0; i < len; i++ในยุคนี้?"

ฉันไม่เห็นด้วยฉันชอบการสร้าง คุณสามารถใช้เวอร์ชันยาวได้หากต้องการ แต่สำนวน Go คือ

var a = []int{1, 2, 3}
for i, v := range a {
    fmt.Println(i, v)
}

for .. rangeสร้างลูปมากกว่าทุกองค์ประกอบและวัสดุสิ้นเปลืองสองค่า - ดัชนีและความคุ้มค่าiv

range ยังทำงานบนแผนที่และช่องต่างๆ

ยังถ้าคุณไม่ชอบforในรูปแบบใด ๆ ที่คุณสามารถกำหนดeach, mapฯลฯ ในไม่กี่บรรทัด:

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
}

พิมพ์

0 : 2
1 : 0
2 : 0
3 : 9

ฉันเริ่มชอบ Go มาก :)


แม้ว่าrangeจะดี แต่ถ้าคอมไพล์เป็นรหัสเดียวกับลูป for-3
Thomas Ahle

19

ไปรับชื่อเสียง stackoverflow ของคุณ

นี่เป็นการแปลคำตอบนี้

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"))
}

ขอขอบคุณScott Wales สำหรับความช่วยเหลืออ่าน ()

สิ่งนี้ดูค่อนข้างแน่นด้วยสองสตริงและสองบัฟเฟอร์ดังนั้นหากผู้เชี่ยวชาญ Go คนใดมีคำแนะนำโปรดแจ้งให้เราทราบ


ฉันไม่แน่ใจว่ามีอะไรผิดปกติกับการจัดรูปแบบ ฉันได้คืนค่าแล้ว

5
ผู้เขียน Go แนะนำให้ใช้gofmtรหัสของคุณ :-)
ℝaphink

ฉันไม่สามารถรวบรวมได้: $ ../go/src/cmd/6g/6g SO.go SO.go: 34: undefined: json.StringToJson
ℝaphink

@Raphink: ภาษามีการเปลี่ยนแปลงตั้งแต่ฉันทำสิ่งนี้

ใช่คุณรู้หรือไม่ว่าอะไรที่ใกล้เคียงที่สุดกับ StringToJson? มันใช้ในการตั้งค่าตัวสร้างภายในตอนนี้เราต้องให้โครงสร้างเนทีฟที่กำหนดไว้ล่วงหน้าของตัวเองหรือไม่?
macbirdie

19

นี่คือตัวอย่างที่ดีของ iota จากโพสต์ของ 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 (!)

5
โปรดทราบว่าไม่จำเป็นต้องใช้เครื่องหมายอัฒภาค
mk12

18

คุณสามารถสลับตัวแปรโดยการกำหนดแบบขนาน:

x, y = y, x

// or in an array
a[j], a[i] = a[i], a[j]

เรียบง่าย แต่มีประสิทธิภาพ


18

นี่คือสำนวนจากเพจEffective Go

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

คำสั่งสวิตช์จะเปิดเป็นจริงเมื่อไม่มีการกำหนดนิพจน์ นี่จึงเทียบเท่ากับ

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

ในขณะนี้รุ่นสวิตช์ดูสะอาดตาสำหรับฉันเล็กน้อย


6
โอ้โฮฉีกจาก VB โดยสิ้นเชิง ;-) ( Switch True…)
Konrad Rudolph

@Konrad เอาชนะฉันให้ได้! :) ฉันเคยใช้สำนวนนั้นในรหัส VB6 มาก่อนและสามารถช่วยให้อ่านได้ในบางสถานการณ์
Mike Spross

'<=' คืออะไร? เกี่ยวข้องกับ '<-' หรือไม่?
ℝaphink

@Raphink: น้อยกว่าหรือเท่ากับ
Paul Ruane


16

เมื่อนำเข้าแพ็กเกจคุณสามารถกำหนดชื่อใหม่เป็นอะไรก็ได้ที่คุณต้องการ:

package main

import f "fmt"

func main() {
    f.Printf("Hello World\n")
}

3
ฉันได้ใช้สิ่งนี้แล้ว: stackoverflow.com/questions/1726698/…

14

พารามิเตอร์ผลลัพธ์ที่ตั้งชื่อ

ผลตอบแทนหรือผลลัพธ์ "พารามิเตอร์" ของฟังก์ชัน Go สามารถกำหนดชื่อและใช้เป็นตัวแปรปกติได้เช่นเดียวกับพารามิเตอร์ขาเข้า เมื่อตั้งชื่อแล้วพวกเขาจะเริ่มต้นเป็นค่าศูนย์สำหรับประเภทเมื่อฟังก์ชันเริ่มต้น ถ้าฟังก์ชันเรียกใช้คำสั่ง return โดยไม่มีอาร์กิวเมนต์ค่าปัจจุบันของพารามิเตอร์ผลลัพธ์จะถูกใช้เป็นค่าที่ส่งคืน

ชื่อไม่บังคับ แต่สามารถทำให้โค้ดสั้นลงและชัดเจนขึ้น: เป็นเอกสารประกอบ ถ้าเราตั้งชื่อผลลัพธ์ของ nextInt จะเห็นได้ชัดว่า int ที่ส่งคืนคืออะไร

func nextInt(b []byte, pos int) (value, nextPos int) {

เนื่องจากผลลัพธ์ที่ตั้งชื่อจะเริ่มต้นและเชื่อมโยงกับผลตอบแทนที่ไม่มีการตกแต่งจึงสามารถทำให้ง่ายขึ้นและชี้แจงได้ นี่คือเวอร์ชันของ io.ReadFull ที่ใช้งานได้ดี:

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;
}

1
ฉันอยากรู้ - มีภาษาอื่นไหม
u0b34a0f6ae

1
Matlab มีบางอย่างที่คล้ายกัน
Dan Lorenc

pascal ใช้ไวยากรณ์ที่คล้ายกันในการส่งคืนค่าหนึ่ง
nes1983

1
@ nes1983 สำหรับผู้ที่ไม่ทราบในภาษาปาสคาลคุณกำหนดค่าที่ส่งคืนให้กับชื่อฟังก์ชันแบบคลาสสิก
fuz

FORTRAN ค่อนข้างมีสิ่งนี้
Hut8

14

จากคำตอบของ James Antill :

foo := <-ch     // This blocks.
foo, ok := <-ch // This returns immediately.

นอกจากนี้ข้อผิดพลาดที่อาจเกิดขึ้น: ความแตกต่างเล็กน้อยระหว่างตัวดำเนินการรับและส่ง:

a <- ch // sends ch to channel a
<-ch    // reads from channel ch

3
ผู้ประกอบการได้รับตัวเองคือตอนนี้การดำเนินการปิดกั้นเป็นของ Go 1.0.3 ข้อมูลจำเพาะได้รับการแก้ไข: golang.org/ref/spec#Receive_operator โปรดลองใช้พฤติกรรมการบล็อก (การหยุดชะงัก) ที่นี่: play.golang.org/p/0yurtWW4Q3
Deleplace

13
/* 
 * 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))
}

4
ฉันขอแนะนำให้ลบชื่อของไซต์การแก้ปัญหารวมทั้งหมายเลขรหัส อาจจะเรียบเรียงคำถามใหม่ เพื่อไม่ให้ปัญหาเสียไปให้ใครสะดุด หรือพยายามโกงโดยการค้นหาปัญหาบนเน็ตสำหรับเรื่องนั้น
Mizipzor

1
สำหรับบันทึก: นี่คืออัลกอริทึมจากalgorithmist.com/index.php/Coin_Changeซึ่งเป็นผลลัพธ์แรกของ Google สำหรับ "coin change"
György Andrasek

13

ฉันชอบที่คุณสามารถกำหนดประเภทใหม่รวมถึง primitives เช่น int กี่ครั้งก็ได้เท่าที่คุณต้องการและแนบวิธีการต่างๆ เช่นเดียวกับการกำหนดประเภท 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))
}

ซึ่งพิมพ์ออกมา

Number:  5 five V

โดยพื้นฐานแล้วการRomanNumber()เรียกนั้นเป็นการร่ายโดยจะกำหนดประเภท int ใหม่เป็นประเภท int ที่เฉพาะเจาะจงมากขึ้น และPrintln()สายString()เบื้องหลัง.


12

การส่งคืนช่อง

นี่เป็นสำนวนที่แท้จริงที่มีความสำคัญมาก: จะป้อนข้อมูลลงในช่องและปิดได้อย่างไรในภายหลัง ด้วยวิธีนี้คุณสามารถสร้างตัวทำซ้ำอย่างง่าย (เนื่องจากช่วงจะยอมรับช่อง) หรือตัวกรอง

// 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;
}

+1. นอกจากนี้คุณสามารถส่งผ่านช่องต่างๆผ่านช่องได้เช่นกัน
György Andrasek

5
แต่ระวังอย่าหลุดจากลูปสำหรับ x: = range chan {} เพราะ goroutine จะรั่วไหลและหน่วยความจำทั้งหมดที่อ้างอิง
Jeff Allen

3
@JeffAllen defer close(outch);เป็นคำสั่งแรกของ goroutine ได้อย่างไร?

1
เลื่อนคิวคำสั่งสำหรับการดำเนินการเมื่อฟังก์ชันส่งคืนไม่ว่าจะใช้จุดส่งคืนใดก็ตาม แต่ถ้าไม่เคยปิดช่องอินพุตฟังก์ชันที่ไม่ระบุชื่อในตัวอย่างนี้จะไม่ออกจากลูป for
Jeff Allen

11

หมดเวลาสำหรับการอ่านช่อง:

ticker := time.NewTicker(ns);
select {
    case v := <- chan_target:
        do_something_with_v;
    case <- ticker.C:
        handle_timeout;
}

ขโมยมาจากเดวีส์หลิว


11
for {
    v := <-ch
    if closed(ch) {
        break
    }
    fmt.Println(v)
}

เนื่องจากช่วงจะตรวจหาช่องทางปิดโดยอัตโนมัติเราจึงสามารถย่อให้สั้นลงได้:

for v := range ch {
    fmt.Println(v)
}

9

มีระบบ make ที่คุณสามารถใช้ใน $ GOROOT / src

ตั้งค่า makefile ของคุณด้วย

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

จากนั้นคุณสามารถใช้เครื่องมือทดสอบอัตโนมัติโดยเรียกใช้ทำการทดสอบหรือเพิ่มแพ็คเกจและวัตถุที่แชร์จาก cgo ไปยัง $ GOROOT ของคุณโดยทำการติดตั้ง


7

godocอีกสิ่งที่น่าสนใจในการไปก็คือว่า คุณสามารถเรียกใช้เป็นเว็บเซิร์ฟเวอร์บนคอมพิวเตอร์ของคุณโดยใช้ไฟล์

godoc -http=:8080

ที่ 8080 เป็นจำนวนพอร์ตและเว็บไซต์ทั้งหมดที่ golang.org localhost:8080เป็นแล้วสามารถดูได้ที่


นี่เป็นโปรแกรมธรรมดาหรือภูต?
György Andrasek

มันเป็นโปรแกรมปกติ
Jeremy

7

นี่คือการใช้งานสแต็ก แสดงวิธีการเพิ่มลงในประเภท

ฉันต้องการทำให้สแต็กเป็นส่วนหนึ่งและใช้คุณสมบัติของสไลซ์ แต่ถึงแม้ว่าฉันจะทำงานได้โดยไม่มีสิ่งtypeนี้ แต่ฉันก็ไม่เห็นไวยากรณ์สำหรับการกำหนดสไลซ์ด้วย a type.

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()
}

10
แทนที่จะใช้คุณสามารถใช้fmt.Printf(...); os.Exit(); panic(...)
notnoop

1
นั่นทำให้เกิดการติดตามสแต็กซึ่งฉันไม่ต้องการ

3
ทำไมถึง จำกัด ? Go เป็นภาษา gc'd ที่มีการจัดการ กองของคุณสามารถลึกได้ตามที่คุณต้องการ ใช้ append () builtin ใหม่ซึ่งจะทำบางอย่างเช่นการจัดสรรใหม่ของ C เมื่อจำเป็น
Jeff Allen

"ไปไม่จำเป็นต้องมียาสามัญ" พวกเขากล่าว
cubuspl42

4

เรียกรหัส c จาก go

เป็นไปได้ที่จะเข้าถึงระดับล่างของ go โดยใช้ c runtime

ฟังก์ชัน C อยู่ในรูปแบบ

void package·function(...)

(สังเกตว่า dot seperator เป็นอักขระ Unicode) โดยที่อาร์กิวเมนต์อาจเป็นประเภท go พื้นฐาน, ชิ้น, สตริง ฯลฯ เพื่อส่งคืนการเรียกค่า

FLUSH(&ret)

(คุณสามารถส่งคืนได้มากกว่าหนึ่งค่า)

ตัวอย่างเช่นในการสร้างฟังก์ชัน

package foo
bar( a int32, b string )(c float32 ){
    c = 1.3 + float32(a - int32(len(b))
}

ใน C ที่คุณใช้

#include "runtime.h"
void foo·bar(int32 a, String b, float32 c){
    c = 1.3 + a - b.len;
    FLUSH(&c);
}

โปรดทราบว่าคุณยังควรประกาศฟังก์ชันในไฟล์ go และคุณจะต้องดูแลหน่วยความจำด้วยตัวเอง ฉันไม่แน่ใจว่าจะเรียกไลบรารีภายนอกโดยใช้สิ่งนี้ได้หรือไม่การใช้ cgo อาจจะดีกว่า

ดูที่ $ GOROOT / src / pkg / runtime สำหรับตัวอย่างที่ใช้ในรันไทม์

ดูคำตอบนี้สำหรับการเชื่อมโยงโค้ด c ++ กับ go


3
มันใช้ "จุดบิน" จริงหรือ? ฉันไม่กล้าแก้ไข แต่ดูเหมือนจะไม่คาดคิดและรุนแรงไปหน่อย
ผ่อนคลายใน

ใช่คุณต้องคอมไพล์ด้วย 6c (หรือ 8c ฯลฯ ) ฉันไม่คิดว่า gcc จัดการกับตัวระบุ Unicode
Scott Wales

1
ฉันคิดว่าระยะเวลา AltGr + เหมือนกัน· แต่ด้วย Unicode ฉันไม่แน่ใจ รู้สึกแปลกใจมากที่เห็นว่าในแหล่งที่มาฉันอ่าน .. ทำไมไม่ใช้สิ่งที่ชอบ ::?
u0b34a0f6ae

ตัวละครคือ MIDDLE DOT U + 00B7 ตัวแยกวิเคราะห์อาจเหลวไหลเพื่อให้เห็นว่านี่เป็นอักขระเพื่อสร้างตัวระบุ c ที่ถูกต้องซึ่งฉันเชื่อว่าจะป้องกันไม่ให้ ::
Scott Wales

4
'·' เป็นเพียงการแฮ็กชั่วคราวโจรรู้สึกประหลาดใจที่ยังคงอยู่ที่นั่นเขาบอกว่ามันจะถูกแทนที่ด้วยสิ่งที่แปลกประหลาดน้อยกว่า
uriel


3

คุณได้ดูการพูดคุยนี้หรือไม่? มันแสดงให้เห็นสิ่งดีๆมากมายที่คุณสามารถทำได้ (ตอนท้ายของการพูดคุย)


2
ใช่ฉันทำ. มันเดือดพล่านถึงขั้น "มีอะไรอีกมากมายเรามาดูหัวข้อต่อไปกัน"
György Andrasek

ใช่เห็นได้ชัดว่ามีเวลาพูดมาก

3

กองซ้อนตามคำตอบอื่น ๆ แต่ใช้ชิ้นส่วนต่อท้ายเพื่อไม่ จำกัด ขนาด

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()
}

3
const ever = true

for ever {
    // infinite loop
}

25
อะแฮ่ม. for { /* infinite loop */ }ก็เพียงพอแล้ว
u0b34a0f6ae

2
แน่นอน. นั่นคือสิ่งที่เกิดขึ้นที่นี่ ฉันชอบforeverคำหลัก แม้แต่ Qt ก็มีมาโครสำหรับสิ่งนั้น
György Andrasek

6
แต่ Go ไม่จำเป็นต้องมีมาโครหรือนามแฝงที่น่ารักในการทำเช่นนี้
u0b34a0f6ae

@ kaizer.se: ประเด็นของ Jurily คือfor ever(หลังจากประกาศตัวแปร) เป็นสิ่งที่น่ารักที่คุณสามารถทำได้ใน Go ถ้าคุณต้องการ ดูเหมือนภาษาอังกฤษ (modulo the blank)
Frank

8
มันเป็นอะไรที่น่ารักที่คุณสามารถทำได้ใน C เช่นกัน .. :-)#define ever (;;)
u0b34a0f6ae

2

testในไดเร็กทอรีหลักมีโปรแกรมขนาดเล็กจำนวนมาก ตัวอย่าง:

  • peano.go พิมพ์แฟกทอเรียล
  • hilbert.go มีการคูณเมทริกซ์
  • iota.go มีตัวอย่างของ iota แปลก ๆ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.