Какво прави go generate ./...? Как?
  
//go:generate command --args
    Къде можете да видите документацията на gitlab.com/ivan/libawesome?
  
Кога работи вградения race detector? Как се ползва?
go test -racego run -racego build -racego install -raceКак мога да направя файл в пакет, който се build-ва само в Линукс?
// +build linux в началото му*_linux.gopackage 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 -pthread -o out goc.c goc.a
Стигне ли се до компилиране на C, забравете за лесно:
Но, за това пък, има много от:
Споделяне на памет, алокирана от Go е възможно ако:
runtime проверява за това и ако види нарушение crash-ва програмата.
unsigned int -> C.uintC.struct_fooerrnon, 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);
}gccgoall: 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) uintptrfunc Offsetof(v ArbitraryType) uintptrfunc Sizeof(v ArbitraryType) uintptrtype ArbitraryType inttype 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))) } }
1 PRINT NOGEN 2 STOCK1 START 0 3 BEGIN BALR 11,0 4 USING *,11 5 MVC NEWOH,OLDOH 6 AP NEWOH,RECPT 7 AP NEWOH,ISSUE 8 EOJ 11 OLDOH DC PL4'9' 12 RECPT DC PL4'4' 13 ISSUE DC PL4'6' 14 NEWOH DS PL4 15 END BEGIN
# TO ENTER A JOB REQUEST REQUIRING NO VAC AREA:
          COUNT     02/EXEC
                
NOVAC     INHINT
          AD        FAKEPRET     # LOC(MPAC +6) - LOC(QPRET)
          TS        NEWPRIO      # PRIORITY OF NEW JOB + NOVAC C(FIXLOC)
          EXTEND
          INDEX     Q            # Q WILL BE UNDISTURBED THROUGHOUT.
          DCA       0            # 2CADR OF JOB ENTERED.
          DXCH      NEWLOC
          CAF       EXECBANK
          XCH       FBANK
          TS        EXECTEM1
          TCF       NOVAC2       # ENTER EXECUTIVE BANK.
Маргарет Хамилтън
TITLE   COUNT
 
A=1                             ;Define a name for an accumulator.
START:  MOVSI A,-100            ;initialize loop counter.
                                ;A contains -100,,0
LOOP:   HRRZM A,TABLE(A)        ;Use right half of A to index.
        AOBJN A,LOOP            ;Add 1 to both halves (-77,,1 -76,,2 etc.)
                                ;Jump if still negative.
        .VALUE                  ;Halt program.
TABLE:  BLOCK 100               ;Assemble space to fill up.
END START                       ;End the assembly./ a3 -- pdp-11 assembler pass 1
assem:
        jsr     pc,readop
        jsr     pc,checkeos
        br      ealoop
        tst     ifflg
        beq     3f
        cmp     r4,$200
        blos    assem
        cmpb    (r4),$21   /if
        bne     2f
        inc     ifflg
2:
        cmpb    (r4),$22   /endif
        bne     assem
        dec     ifflg
        br      assemstrtolower      public
                link    a6,#0           ;Set up stack frame
                movea   8(a6),a0        ;A0 = src, from stack
                movea   12(a6),a1       ;A1 = dst, from stack
loop            move.b  (a0)+,d0        ;Load D0 from (src)
                cmpi    #'A',d0         ;If D0 < 'A',
                blo     copy            ;skip
                cmpi    #'Z',d0         ;If D0 > 'Z',
                bhi     copy            ;skip
                addi    #'a'-'A',d0     ;D0 = lowercase(D0)
copy            move.b  d0,(a1)+        ;Store D0 to (dst)
                bne     loop            ;Repeat while D0 <> NUL
                unlk    a6              ;Restore stack frame
                rts                     ;Return
                endident slice
         V6        0               ; initialize S
         A4        S0              ; initialize *x
         A5        S1              ; initialize *y
         A3        S2              ; initialize i
loop     S0        A3
         JSZ       exit            ; if S0 == 0 goto exit
         VL        A3              ; set vector length
         V11       ,A4,1           ; load slice of x[i], stride 1
         V12       ,A5,1           ; load slice of y[i], stride 1
         V13       V11 *F V12      ; slice of x[i] * y[i]
         V6        V6 +F V13       ; partial sum
         A14       VL              ; get vector length of this iteration
         A4        A4 + A14        ; *x = *x + VL
         A5        A5 + A14        ; *y = *y + VL
         A3        A3 - A14        ; i = i - VL
         J        loop
 exitИмат доста обща структура:
subroutine header
label:
    instruction operand...    ; comment
    ...Чрез собствен assembler, който след това лесно се превежда до реалния на всяка машина.
Нека разгледаме go програмата
package add
func add(a, b int) int {
    return a + b
}И сега генерирания assembly
TEXT add(SB), $0-12
    MOVL    a+4(FP), BX
    ADDL    b+8(FP), BX
    MOVL    BX, 12(FP)
    RETTEXT add(SB), $0-24
    MOVQ    b+16(FP), AX
    MOVQ    a+8(FP), CX
    ADDQ    CX, AX
    MOVQ    AX, 24(FP)
    RETTEXT add(SB), $-8-24
    MOVD    a(FP), R0
    MOVD    b+8(FP), R1
    ADD     R1, R0
    MOVD    R0, 16(FP)
    RETTEXT add(SB), $0-24
    MOVD    a(FP), R1
    MOVD    b+8(FP), R2
    ADD     R2, R1, R1
    MOVD    R1, 16(FP)
    RETTEXT add(SB), $0-24
    MOVD    a(FP), R2
    MOVD    b+8(FP), R3
    ADD     R3, R2
    MOVD    R2, 16(FP)
    RETНа практика са еднакви.
real -> go assemblygithub.com/golang/go/blob/master/src/cmd/internal/obj/arm64/asm7.go
export GODEBUG="name=flag"
Пример:
export GODEBUG="gctrace=2,invalidptr=1"
Позволява:
GOGC=100GOGC=off спира събирането на боклук изцялоGOMAXPROCS(n int) от пакета runtime