Как се подават флагове за регулярни изрази в Go?
Какво е error
?
Къде пишем документацията на нашите фунцкии, структури и пакети?
Как се въстановяваме от паника?
recover
в defer
defer func() { if r := recover(); r != nil { // There was a panic } }()
package main /* #include <stdlib.h> */ import "C" func Random() int { return int(C.random()) } func Seed(i int) { C.srandom(C.uint(i)) }
#cgo
са "специални"// #cgo CFLAGS: -DPNG_DEBUG=1 // #cgo amd64 386 CFLAGS: -DX86=1 // #cgo LDFLAGS: -lpng // #include <png.h> import "C"
// #cgo pkg-config: png cairo
package goc import "C" //export GreetFromGo func GreetFromGo(name string) { println("Hello from Go, ", name) } func main() { // Needed by cgo in order to generate a library }
go build -buildmode=c-archive -o goc.a goc.go
goc.a
и goc.h
файловеgoc.h
, освен малко boilerplate, ще има и:extern void GreetFromGo(GoString p0);
GoString
е част от споменатия boilerplate#include "goc.h" #include <stdio.h> int main() { printf("Hi, I am a C program.\n"); GoString name = {"Doycho", 4}; GreetFromGo(name); return 0; }
gcc -o out goc.c goc.a
Стигне ли се до компилиране на C, забравете за лесно:
Но, за това пък, има много от:
unsigned int
-> C.uint
C.struct_foo
errno
n, err := C.sqrt(-1)
package main // typedef int (*intFunc) (); // // int // bridge_int_func(intFunc f) // { // return f(); // } // // int fortytwo() // { // return 42; // } import "C" import "fmt" func main() { f := C.intFunc(C.fortytwo) fmt.Println(int(C.bridge_int_func(f))) // Output: 42 }
package main func Add(a, b int) int { return a + b }
#include <stdio.h> extern int go_add(int, int) __asm__ ("example.main.Add"); int main() { int x = go_add(2, 3); printf("Result: %d\n", x); }
gccgo
all: main main: foo.o bar.c gcc foo.o bar.c -o main foo.o: foo.go gccgo -c foo.go -o foo.o -fgo-prefix=example clean: rm -f main *.o
Декларира невинно изглеждащите:
func Alignof(v ArbitraryType) uintptr
func Offsetof(v ArbitraryType) uintptr
func Sizeof(v ArbitraryType) uintptr
type ArbitraryType int
type Pointer *ArbitraryType
реално тези дефиниции съществуват главно за документация, имплементацията е в компилатора.
unsafe.Pointer има четири важни харектеристики
Това е практическо заобикаляне на типовата система в Go.
package main /* #include <stdlib.h> */ import "C" import ( "fmt" "unsafe" ) func main() { cs := C.CString("42") // alloc on C's heap defer C.free(unsafe.Pointer(cs)) // don't leak answer := C.atoi(cs) fmt.Println(answer) }
package main
import "unsafe"
import "fmt"
type slice struct { array unsafe.Pointer size, _cap int } func main() { var p = []string{"Hello", " "} p = append(p, "World!") var s = (*slice)(unsafe.Pointer(&p)) var sizeOfString = unsafe.Sizeof("") fmt.Printf("size=%d, cap=%d\n", s.size, s._cap) for i := 0; s.size > i; i++ { fmt.Printf("[%d]: `%s`\n", i, *(*string)(unsafe.Pointer(uintptr(s.array) + uintptr(i)*sizeOfString))) } }
export GODEBUG="name=flag"
Пример:
export GODEBUG="gctrace=2,invalidptr=1"
Позволява:
GOGC=100
GOGC=off
спира събирането на боклук изцяло