Go is
Programming Language
int a[10];
a[11] = 10;
void allocate_forever(void) {
int *a = malloc(10 * sizeof(int));
a[0] = 10;
}
struct student {
int id;
char surname[255];
char forename[255];
};
#define students_foreach_loop(stds, element) \
struct students_el *element ## _el = stds->head; \
const struct student *element = element ## _el->student; \
for (; element ## _el != NULL; element ## _el = element ## _el->next, element = element ## _el ? element ## _el->student : NULL)
students_foreach_loop(stds, el) {
fprintf(fp, "Name: %s\n", el->name);
fprintf(fp, "ID: %s\n", el->id);
fprintf(fp, "\n");
}
x := 0
instead of int x = 0;
).go get
) and
online package documentation.select
statement.
package main
import "fmt"
func main() {
fmt.Printf("Hello, دنیا\n")
}
import
declaration must follow the
package
declaration.func
, the name of the function, a parameter
list (empty for main), a result list (also empty here), and the body of
the function - the statements that define what it does - enclosed in
braces.Code Time.go
links to see the source
codecurl
to download the source code
curl https://raw.githubusercontent.com/1995parham-teaching/go-lecture/main/00-hello-world/main.go > hello-world.go
pacman -Syu go
apt install golang-go
sudo snap install go --classic
brew install go
scoop install go
Maintained precisely:
const e = 2.71828182845904523536028747135266249775724709369995957496696763
const third = 1/3
Typed or without type:
const M64 int64 = 1<<20
const M = 1<<20
Evaluated at compile-time:
const big = 1<<100 / 1e30 // valid constant expression
var
name
type
=
expression
name
:=
expression
// inside functions only
Statically typed:
var x int
var s, t string
Implicitly or explicitly initialized:
var x int // x = 0
var s, t string = "foo", "bar" // multiple assignment
var x = 42 // int
var s, b = "foo", true // string, bool
Short variable declaration:
x := 42
s, b := "foo", true
x := 1
p := &x // p, of type *int, points to x
fmt.Println(*p) // 1
*p = 2 // equivalent to x = 2
fmt.Println(x) // 2
true false iota nil
int int8 int16 int32 int64
uint uint8 uint16 uint32 uint64 uintptr
float32 float64 complex128 complex64
bool byte rune string error
make len cap new append copy close delete
complex real imag
panic recover
break default func interface select
case defer go map struct
chan else goto package switch
const fallthrough if range type
continue for import return var
x := 42
y := x + 10
var c = (f - 32) * 5 / 9
var x uint8 = 1 << 1 | 1 << 5
var y uint8 = 1 << 1 | 1 << 2
fmt.Printf("%08b\n", x) // "00100010"
fmt.Printf("%08b\n", y) // "00000110"
fmt.Printf("%08b\n", x&y) // "00000010"
fmt.Printf("%08b\n", x|y) // "00100110"
fmt.Printf("%08b\n", x^y) // "00100100"
new
new(T)
create an unnamed variable of type T,
initializes it to the zero value of T, and return its address, which is
a value of type *T
func newInt() *int {
return new(int)
}
func newInt() *int {
var dummy int
return &dummy
}
// tuple assignment
a, b = b, a // swap
f, err = os.Open(filename) // multiple assignment
func gcd(x, y int) int {
for y != 0 {
x, y = y, x % y
}
return x
}
if x < y {
return x
} else {
return y
}
switch day {
case Mon:
...
// break is implicit
case Tue, Wed:
...
}
for
syntax
// a traditional infinite loop
for {
// ...
}
for initialization; condition; post {
// zero or more statements
}
// a traditional "while" loop
for condition {
// ...
}
range
over arrays, slices, and mapsrange
produces a pair of
values: the index and the value of the element at that index.
for i, num := range numbers { ... }
for city, pop := range population { ... }
package main
import "fmt"
func Fibonacci(n int) int {
if n == 0 || n == 1 {
return 1
} else {
return Fibonacci(n-1) + Fibonacci(n-2)
}
}
func main() {
fmt.Printf("%d\n", Fibonacci(10))
}
package "main"
import "fmt"
func main() {
var n int
fmt.Scanf("%d", &n)
fmt.Printf("%d\n", n)
}
%d | decimal integer |
%x, %o, %b | integer in hexadecimal, octal, binary |
%f, %g, %e | floating-point number: 3.141593 3.141592653589793 3.141593e+00 |
%t | boolean: true or false |
%c | rune (Unicode code point) |
%s | string |
%q | quoted string "abc" or rune 'c' |
%v | any value in natrual format |
%T | type of any value |
%% | literal percent sign (no operand) |
len
function the number of bytes (not runes)
in a string, and the index operation s[i]
retrieves the
i-th byte of string s, where 0 <= i < len(s)
s := "hello, world"
fmt.Println(len(s)) // 12
fmt.Println(s[0], s[7]) // 'h' and 'w'
s[0] = 'L' // compile error: cannot assign to s[0]
bytes
strings
strconv
unicode
go doc bytes
fmt.Sprintf
; another is to use the function
strconv.Itoa
.strconv.FormatInt()
and strconv.FormatUint
can
be used to format numbers in a different basefmt.Printf
verbs %b
, %d
,
%o
, and %x
are often more convenient thatn
Format
functions
x := 123
y := fmt.Sprintf("%d", x)
fmt.Println(y, strconv.Itoa(x)) // "123 123"
strconv.Atoi
or strconv.ParseInt
, or
strconv.ParseUint
for unsigned integersParseInt
gives the size of the
integer type that the result must fit intoint64
, which
you can then convert to a smaller typefmt.Sscanf
is useful for parsing input that consists of
orderly mixtures of strings and number all on a single line
x, err := strconv.Atoi("123") // x is an int
y, err := strconv.ParseInt("123", 10, 64) // base 10, up to 64 bits
var a [3]int // array of 3 integers
fmt.Println(a[0]) // print the first element
fmt.Println(a[len(a) - 1]) // print the last element, a[2]
a := [2]int{1, 2}
b := [...]int{1, 2}
c := [2]int{1, 3}
fmt.Println(a == b, a == c, b == c) // "true false false"
d := [3]int{1, 2}
fmt.Prinln(a == d) // compile error: cannot compare [2]int == [3]int
// Print the indices and elements.
for i, v := range a {
fmt.Printf("%d %d\n", i, v)
}
// Print the elements only.
for _, v := range a {
fmt.Printf("%d\n", v)
}
[]T // slice of T
s[i:j]
, where 0 <= i <=
j <= cap(s), creates a new slice that refers to elements i through
j - 1 of the sequence s.
len(s)
s[i]
s[i:j]
append(s, x) // append element x to slice s and return new slice
make
package main
type Sample struct {
S1 int
S2 int
S3 string
private float64
}
func main() {
var smp Sample
smp.S1 = 10
smp.S2 = 20
smp.S3 = "Hello World"
}
S1
, S2
,
S3
are public and can be accessed from
anywhere.private
is private and is only visible
to code in the same package.
package main
import "fmt"
type Example struct {
Val string
count int
}
// define a custom type based on go standard types
type integer int
func (i integer) log() {
fmt.Printf("%d\n", i)
}
// pointer reciever which can change 'example' fields
func (e *Example) Log() {
e.count++
fmt.Printf("%d %s\n", e.count, e.Val)
}
func main() {
var i integer
exm := Example{
Val: "Example",
count: 10}
i.log()
exm.Log()
}
package main
import "fmt"
type Printer interface {
Print()
}
type Foo struct {
X, Y int
}
type Bar struct {
X, Y float64
}
func (f Foo) Print() {
fmt.Printf("%d %d\n", f.X, f.Y)
}
func (b Bar) Print() {
fmt.Printf("%g %g\n", b.X, b.Y)
}
package main
func main() {
one := 1
var float float32
float = float32(one)
}
package main
import "fmt"
type empty interface{}
type example struct {
A int
}
func main() {
one := 1
var i empty = one
j := example{A: 10}
var k empty = j
fmt.Println(k.(example).A)
}
type Point interface {
Distance() float64
ImageOnX() float64
ImageOnY() float64
}
type Cartesian struct {
X float64
Y float64
}
func (c *Cartesian) Distance() float64 {
return math.Sqrt(c.X*c.X + c.Y*c.Y)
}
func (c *Cartesian) ImageOnX() float64 {
return c.X
}
func (c *Cartesian) ImageOnY() float64 {
return c.Y
}
type Polar struct {
R float64
Teta float64
}
func (p *Polar) Distance() float64 {
return p.R
}
func (p *Polar) ImageOnX() float64 {
return p.R * math.Cos(p.Teta)
}
func (p *Polar) ImageOnY() float64 {
return p.R * math.Sin(p.Teta)
}
func main() {
p := Polar{
R: 1,
Teta: math.Pi / 2,
}
c := Cartesian{
X: 3,
Y: 4,
}
fmt.Printf("%g %g\n", p.Distance(), c.Distance())
fmt.Printf("%g %g\n", c.ImageOnX(), c.ImageOnY())
fmt.Printf("%g %g\n", p.ImageOnX(), p.ImageOnY())
}
package main
import (
"fmt"
"math"
)
type Point interface {
Distance() float64
ImageOnX() float64
ImageOnY() float64
}
type Cartesian struct {
X float64
Y float64
}
func (c *Cartesian) Distance() float64 {
return math.Sqrt(c.X*c.X + c.Y*c.Y)
}
func (c *Cartesian) ImageOnX() float64 {
return c.X
}
func (c *Cartesian) ImageOnY() float64 {
return c.Y
}
type Polar struct {
R float64
Teta float64
}
func (p *Polar) Distance() float64 {
return p.R
}
func (p *Polar) ImageOnX() float64 {
return p.R * math.Cos(p.Teta)
}
func (p *Polar) ImageOnY() float64 {
return p.R * math.Sin(p.Teta)
}
func main() {
p := Polar{
R: 1,
Teta: math.Pi / 2,
}
c := Cartesian{
X: 3,
Y: 4,
}
fmt.Printf("%g %g\n", p.Distance(), c.Distance())
fmt.Printf("%g %g\n", c.ImageOnX(), c.ImageOnY())
fmt.Printf("%g %g\n", p.ImageOnX(), p.ImageOnY())
}
└── gopherguides
└── greet
└── greet.go
package greet
import "fmt"
func Hello() {
fmt.Println("Hello, World!")
}
└── gopherguides
└── example
└── main.go
package main
import "github.com/gopherguides/greet"
func main() {
greet.Hello()
}
go.mod
file, together with
information about the module's
dependencies.golang.org/x/net
contains a
package in the directory html
. That
package's path is golang.org/x/net/html
.
> go mod init github.com/1995parham-teaching/go-lecture/echo
> go get github.com/labstack/echo/v4
e := echo.New()
e.POST("/hello", func (c echo.Context) error {
c.JSON(http.StatusOK, "Hello World")
})
go
statement launches a function call
as a goroutine
go f()
go f(x, y, ...)
Function f is launched as 3 different goroutines, all running concurrently:
package main
import (
"fmt"
"time"
)
func f(msg string, delay time.Duration) {
for {
fmt.Println(msg)
time.Sleep(delay)
}
}
func main() {
go f("A--", 300*time.Millisecond)
go f("-B-", 500*time.Millisecond)
go f("--C", 1100*time.Millisecond)
time.Sleep(20 * time.Second)
}
chan int
chan<- string // send-only channel
<-chan T // receive-only channel
var ch chan int
ch := make(chan int) // declare and initialize with newly made channel
ch <- 1 // send value 1 on channel ch
x = <-ch // receive a value from channel ch (and assign to x)
Each goroutine sends its results via channel ch:
func f(msg string, delay time.Duration, ch chan string) {
for {
ch <- msg
time.Sleep(delay)
}
}
The main goroutine receives (and prints) all results from the same channel:
func main() {
ch := make(chan string)
go f("A--", 300*time.Millisecond, ch)
go f("-B-", 500*time.Millisecond, ch)
go f("--C", 1100*time.Millisecond, ch)
for i := 0; i < 100; i++ {
fmt.Println(i, <-ch)
}
}