- 快召唤伙伴们来围观吧
- 微博 QQ QQ空间 贴吧
- 文档嵌入链接
- <iframe src="https://www.slidestalk.com/u3793/Gos_Hidden_Pragmas28633?embed" frame border="0" width="640" height="360" scrolling="no" allowfullscreen="true">复制
- 微信扫一扫分享
Go's Hidden Pragmas
展开查看详情
1 .Go’s Hidden #pragmas GopherChina 2017
2 . @davecheney Go programmer from Sydney, Australia
3 .But first, a history lesson.
4 . Perl use strict; use strict "vars"; use strict "refs"; use strict "subs"; use strict; no strict "vars";
5 . Javascript "use strict";
6 . Rust #[inline(always)] fn super_fast_fn() { #[cfg(target_os = "macos")] mod macos_only {
7 .Warning: History time
8 .ALGOL 68 pragmat
9 . C #pragma pack(2) struct T { int i; short j; double k; };
10 .Does Go have pragmas?
11 .Yes. Go has pragmas //
12 . They're actually called pragmas in the source
13 . syscall/syscall_linux_amd64.go //go:noescape func gettimeofday(tv *Timeval) (err Errno)
14 .cmd/compile/internal/gc/testdata/arith.go //go:noinline func lshNop1(x uint64) uint64 { // two outer shifts should be removed return (((x << 5) >> 2) << 2) }
15 . runtime/atomic_pointer.go //go:nosplit func atomicstorep(ptr unsafe.Pointer, new unsafe.Pointer) { writebarrierptr_prewrite((*uintptr)(ptr), uintptr(new)) atomic.StorepNoWB(noescape(ptr), new) }
16 .A word of caution 🚨
17 . "Useful" is always true for a feature request. The question is, does the usefulness justify the cost? The cost here is continued proliferation of magic comments, which are becoming too numerous already. –Rob Pike
18 .//go:noescape
19 . Escape Analysis func NewBook() *Book { b := Book{Mice: 12, Men: 9} return &b }
20 . Escape Analysis (cont.) func BuildLibrary() { b := Book{Mice: 99: Men: 3} AddToCollection(&b) }
21 .Answer: it depends 🤔
22 . b does not escape func AddToCollection(b *Book) { b.Classification = "fiction" }
23 . b escapes var AvailableForLoan []*Book func AddToCollection(b *Book) { AvailableForLoan = append(AvailableForLoan, b) }
24 . os.File.Read f, _ := os.Open("/tmp/foo") buf := make([]byte, 4096) n, _ := f.Read(buf)
25 . os.File.Read // Read reads up to len(b) bytes from the File. // It returns the number of bytes read and any error encountered. // At end of file, Read returns 0, io.EOF. func (f *File) Read(b []byte) (n int, err error) { if err := f.checkValid("read"); err != nil { return 0, err } n, e := f.read(b) if e != nil { if e == io.EOF { err = e } else { err = &PathError{"read", f.name, e} } } return n, err }
26 . golang.org/issue/4099 commit fd178d6a7e62796c71258ba155b957616be86ff4 Author: Russ Cox <rsc@golang.org> Date: Tue Feb 5 07:00:38 2013 -0500 cmd/gc: add way to specify 'noescape' for extern funcs A new comment directive //go:noescape instructs the compiler that the following external (no body) func declaration should be treated as if none of its arguments escape to the heap. Fixes #4099. R=golang-dev, dave, minux.ma, daniel.morsing, remyoudompheng, adg, agl, iant CC=golang-dev https://golang.org/cl/7289048
27 . bytes.IndexByte (circa Go 1.5) package bytes //go:noescape // IndexByte returns the index of the first instance of c in s, // or -1 if c is not present in s. func IndexByte(s []byte, c byte) int // ../runtime/asm_$GOARCH.s
28 .Can you use //go:noescape in your code?
29 .//go:norace