Go Γλώσσα Προγραμματισμού - Φύλλο Οδηγιών
Η Go (γνωστή και ως Golang) είναι μια στατικά τυποποιημένη, μεταγλωττισμένη γλώσσα που αναπτύχθηκε από τους Robert Griesemer, Rob Pike και Ken Thompson της Google. Η σύνταξη της Go είναι παρόμοια με τη C, αλλά διαθέτει χαρακτηριστικά όπως: ασφάλεια μνήμης, GC (garbage collection), δομική τυποποίηση και ταυτόχρονο προγραμματισμό τύπου CSP.
Hello world
package main
import "fmt"
func main() {
message := greetMe("world")
fmt.Println(message)
}
func greetMe(name string) (string) {
return "Hello, " + name + "!"
}
$ go buildΜεταβλητές (Variables)
Δήλωση μεταβλητής
var msg string
msg = "Hello"Σύντομη δήλωση
msg := "Hello"Σταθερές (Constants)
const Phi = 1.618Οι σταθερές μπορούν να είναι χαρακτήρες (characters), συμβολοσειρές (strings), λογικές τιμές (booleans) ή αριθμητικές τιμές.
Βασικοί Τύποι
Συμβολοσειρές (Strings)
str := "Hello"
str := `Multiline
string`Ο τύπος των συμβολοσειρών είναι string.
Αριθμητικοί Τύποι
Τυπικοί τύποι
num := 3 // int
num := 3. // float64
num := 3 + 4i // complex128
num := byte('a') // byte (alias για uint8)Άλλοι τύποι
var u uint = 7 // uint (unsigned)
var p float32 = 22.7 // 32-bit floatΔείκτες (Pointers)
func main () {
b := *getPointer()
fmt.Println("Value is", b)
}
func getPointer () (myPointer *int) {
a := 234
return &a
}Ένας δείκτης δείχνει στη θέση μνήμης μιας μεταβλητής. Η Go διαθέτει πλήρη διαχείριση απορριμμάτων (garbage collection).
Πίνακες (Arrays)
// var numbers [5]int
numbers := [...]int{0, 0, 0, 0, 0}Το μέγεθος των πινάκων είναι σταθερό.
Slices (Τμήματα)
slice := []int{2, 3, 4}
slice := []byte("Hello")Σε αντίθεση με τους πίνακες, τα slices έχουν δυναμικό μέγεθος.
Έλεγχος Ροής
Συνθήκες (Conditional logic)
if day == "sunday" || day == "saturday" {
rest()
} else if day == "monday" && isTired() {
groan()
} else {
work()
}Δηλώσεις μέσα στην if
if _, err := getResult(); err != nil {
fmt.Println("Uh oh")
}Η δήλωση if μπορεί να εκτελέσει μια απλή δήλωση πριν από την έκφραση της συνθήκης.
Switch
switch day {
case "sunday":
// οι περιπτώσεις δεν "συνεχίζουν" (fall through) από προεπιλογή!
fallthrough
case "saturday":
rest()
default:
work()
}Συναρτήσεις
Lambdas
myfunc := func() bool {
return x > 10000
}Οι συναρτήσεις είναι αντικείμενα πρώτης τάξης (first-class objects).
Πολλαπλοί τύποι επιστροφής
a, b := getMessage()
func getMessage() (a string, b string) {
return "Hello", "World"
}Καθορισμένες τιμές επιστροφής
func split(sum int) (x, y int) {
x := sum * 4 / 9
y := sum - x
return
}Δηλώνοντας ονόματα για τις τιμές επιστροφής, η εντολή return (χωρίς ορίσματα) θα επιστρέψει τις μεταβλητές με αυτά τα ονόματα.
Πακέτα (Packages)
Φόρτωση (Loading)
import "fmt"
import "math/rand"
import (
"fmt" // παρέχει fmt.Println
"math/rand" // παρέχει rand.Intn
)Και οι δύο τρόποι είναι ίδιοι.
Ψευδώνυμα (Aliases)
import r "math/rand"
r.Intn()Ονόματα κλήσης
func Hello () {
···
}Τα ονόματα κλήσης που εξάγονται ξεκινούν με κεφαλαίο γράμμα.
Packages
package helloΚάθε αρχείο πακέτου πρέπει να ξεκινά με τη δήλωση package.
Ταυτόχρονη Εκτέλεση (Concurrency)
Goroutines
func main() {
// Ένα "κανάλι" (channel)
ch := make(chan string)
// Έναρξη ταυτόχρονων ρουτινών
go push("Moe", ch)
go push("Larry", ch)
go push("Curly", ch)
// Ανάγνωση 3 αποτελεσμάτων
// (Εφόσον οι goroutines είναι ταυτόχρονες,
// η σειρά δεν είναι εγγυημένη!)
fmt.Println(<-ch, <-ch, <-ch)
}
func push(name string, ch chan string) {
msg := "Hey, " + name
ch <- msg
}Τα κανάλια είναι αντικείμενα επικοινωνίας ασφαλή για ταυτόχρονη χρήση, που χρησιμοποιούνται μεταξύ των goroutines.
Κανάλια με Buffering
ch := make(chan int, 2)
ch <- 1
ch <- 2
ch <- 3
// fatal error:
// all goroutines are asleep - deadlock!Τα κανάλια με buffer περιορίζουν τον αριθμό των μηνυμάτων που μπορούν να κρατήσουν.
Κλείσιμο καναλιού
ch <- 1
ch <- 2
ch <- 3
close(ch)Περίληψη καναλιού μέχρι να κλείσει:
for i := range ch {
···
}Κλείσιμο αν ok == false:
v, ok := <- chΈλεγχος Σφαλμάτων
Defer
func main() {
defer fmt.Println("Done")
fmt.Println("Working...")
}Καθυστερεί την εκτέλεση μιας συνάρτησης μέχρι να επιστρέψει η συνάρτηση που την περιβάλλει. Τα ορίσματα αξιολογούνται αμέσως, αλλά η κλήση της συνάρτησης εκτελείται στο τέλος.
Συναρτήσεις Defer
func main() {
defer func() {
fmt.Println("Done")
}()
fmt.Println("Working...")
}Οι Lambdas είναι πιο κατάλληλες για μπλοκ καθυστέρησης (defer blocks).
Structure (Δομές)
Ορισμός
type Vertex struct {
X int
Y int
}
func main() {
v := Vertex{1, 2}
v.X = 4
fmt.Println(v.X, v.Y)
}Literals (Κυριολεκτικά)
v := Vertex{X: 1, Y: 2}
// Τα ονόματα των πεδίων μπορούν να παραλειφθούν
v := Vertex{1, 2}
// Το Y είναι έμμεσο
v := Vertex{X: 1}Μπορείτε επίσης να καθορίσετε τα ονόματα των πεδίων.
Δείκτες σε δομές
v := &Vertex{1, 2}
v.X = 2Όταν το v είναι δείκτης, το v.X και το (*v).X είναι το ίδιο.
Μέθοδοι (Methods)
Δέκτες (Receivers)
type Vertex struct {
X, Y float64
}
func (v Vertex) Abs() float64 {
return math.Sqrt(v.X * v.X + v.Y * v.Y)
}
v: = Vertex{1, 2}
v.Abs()Δεν υπάρχουν κλάσεις, αλλά μπορείτε να χρησιμοποιήσετε δέκτες για να ορίσετε συναρτήσεις σε τύπους.
Τροποποίηση
func (v *Vertex) Scale(f float64) {
v.X = v.X * f
v.Y = v.Y * f
}
v := Vertex{6, 12}
v.Scale(0.5)
// Το `v` ενημερώνεται