Сервис для заказа графического дизайна и копирайтинга GoDesigner
Решайте задачи вашего бренда с помощью конкурса профессиональных дизайнеров
Получите 100 креативных идей по цене одной
РЕЗУЛЬТАТЫ ПОИСКА
Срок: от дней
Решений: ~
Стоимость: 16 350 р.
ЗАКАЗАТЬЗавершенные проекты:
ДОПОЛНИТЕЛЬНЫЕ ПРЕДЛОЖЕНИЯ
срок: 10 дней;
решений: 100;
стоимость: 23 000 р.
ЗАКАЗАТЬСтудия из лучших дизайнеров GoDesigner,
проверенных исполнителей сайта
Над вашим брендом гарантировано будут работать профессионалы.
100% результат в конкурсе
всегда.
Оперативно
и выгодно
Вы сами решаете, сколько платить исполнителю и когда необходим дизайн, а мы отвечаем за результат. Мы вернем деньги, если вам не понравится!
Больше решений
за те же деньги
Если вы обратитесь в агентство, вам предоставят 3 варианта на выбор. На GoDesigner вы получите ~100 решений на задачу
Прозрачно
и гарантированно
Нам можно доверить крупный бюджет, получить документальное подтверждение для потраченных денег и оформить права на результат.
ПРИМЕРЫ ПРОЕКТОВ
Недвижимость / Строительство Автомобили / Транспорт Финансы / Бизнес Еда / Напитки Реклама / Коммуникации Туризм / Путешествие Спорт Образование / Наука Красота / Мода Развлечение / Музыка Искусство / Культура Животные Дети Охрана / Безопасность Медицина / Здоровье Компьютеры / IT
Генеральный директор рекламного агентства LaFedja
Подробнее…Альберт Федченко
На данный момент совмещает преподавательскую деятельность с работой в ведущем дизайн-агентстве Краснодара LaFedja. Каждый день просматривает и анализирует cотни новых работ лучших мировых агентств и дизайнеров в области графического дизайна, упаковки и веб-технологий.
Основатель и арт-директор креативного агентства nOne
Подробнее…Станислав Ефремов
Более 10 лет возглавляет творческое подразделение агентства nOne. Решает креативные задачи в области брендинга, дизайна, и рекламы компаний Вимм-Билль-Данн, Газпромбанк, Intel, Motorola, Северсталь, Росатом, FSC, Трансаэро и многих других.
Генеральный директор компании BrandAid
Подробнее…Валентин Перция
С 1995 года работал в международных РА (Euro RSCG World Wide, Ark/JWT, Bates Ukraine) на позициях от стратегического планировщика до заместителя директора. В 2000 году создал компанию BrandAid. Специализация – создание и развитие брендов. Компания разработала более 100 новых брендов (Мягков, Сильпо, Винодел).
4 534
Завершенных проектов
54 577
Исполнителей зарегистрировано
на сайте
401
Новых идей загружено за последние 24 часа
9 лет
стаж работы
ПРИМЕРЫ РАБОТ ДЛЯ ВАШЕЙ СФЕРЫ
Студия GoDesigner: новое приглашение!
Приглашение активно, пока в конкурсе сохраняются вакантные места для участников студии GoDesigner (1−15 в зависимости от категории и награды). Подтвердите согласие на участие в проекте или отклоните приглашение. Не принимайте приглашение, если не сможете участвовать в конкурсе!
Если вы выиграете конкурс как представитель студии, то гонорар будет переведен без удержания комиссии.
Подробнее:
Дизайнеру: что такое студия GoDesigner?
Договор отчуждения исключительных прав
Сервис для заказа графического дизайна и копирайтинга GoDesigner
Сервис для заказа графического дизайна и копирайтинга GoDesignerУчаствуйте в проекте
и Зарабатывайте деньги!
Принимайте участие в мозговом штурме наравне с именитыми креативщиками и зарабатывайте, как опытные рекламщики.
GoDesigner — это уникальный шанс участвовать в интересных проектах и работать для известных брендов. Вы решаете, с кем работать, что дает вам безграничные возможности для отличных решений!
У нас нет менеджеров и модераторов, выкладывайте решения прямо на сайт, комментируйте их и направляйте клиента! Все ваши идеи имеют право на победу.
На GoDesigner выигрывает лучший дизайн, и тут не имеет значения ваше имя, резюме, опыт работы или портфолио. Самые удачные творческие идеи не всегда рождаются на Мэдисон Авеню.
Недобросовестные заказчики не используют вашу идею, не заплатив за неё. Мы обеспечим надежное вознаграждение победителю за приложенные усилия.
На старт – внимание – марш!
Вы уверены, что хотите удалить черновик проекта?
Вы не сможете восстановить черновик после удаления.
Удалить ОтменаGo: A Documentary
by Changkun Ou <changkun.de>
(and many inputs from contributors)This document collects many interesting (publicly observable) issues, discussions, proposals, CLs, and talks from the Go development process, which intents to offer a comprehensive reference of the Go history.
Disclaimer
- Most of the texts are written as subjective understanding based on public sources
- Factual and typo errors may occur. Referring to the original link if some text conflicts to your understanding
- PRs are very welcome for new content submission, bug fixes, and typo fixes
- Use Issues for discussions
Sources
There are many sources for digging the documents that relate to Go’s historical design, and here are some of the official sources:
Origin
Go is a big project driven by a tiny group of people and the crowd of wisdom from the language user community. Here are some core committers to the project that you might interest in following their excellent work.
Go’s origin is attractive without doubts. By listening to the talks held by these people, you could learn more about their oral history and fun stories behind the great work.
For instance, here are some exciting talks regarding the historical feats
in Go might be your starting points (as a subjective recommendation): talk/rob2007
, talk/rob2009
, talk/rob2010b
, talk/rob2010d
, talk/rob2011a
, talk/rob2013a
, talk/rob2019
, talk/robert2015
, talk/russ2014
, steve2019b
, etc.
Committers
Core Authors
The Go was created by Rob, Robert, and Ken initially because Rob were suffered by the slow C++ compiling time, talked to Robert, and luckily Ken was in the next office. Later, Ian joined the project since he showed huge interests and wrote the gccgo. Rob and Ken are retired. Robert and Ian currently work on adding generics to Go. Russ is also one of the core authors of the project in the early stage. Back then, he was a newcomer at Google, and Rob invited Russ for joining the Go team since he knew Russ from way back because of the Plan 9 project. Russ did many fundamental work for the early Go compiler, runtime, as well as the leap of Go 1.5 bootstrap. Now, Russ is the tech leader of the Go team.
- Rob Pike. (Robert C. Pike, M. Sc.) Website, Blog, GitHub, Twitter, Reddit. (Retired)
- Alma mater: University of Toronto (BS), California Institute of Technology
- talk/rob2007 Advanced Topics in Programming Languages: Concurrency/message passing Newsqueak. May 9, 2007
- talk/rob2009 The Go Programming Language. Nov 27, 2009.
- talk/rob2010a Go Programming. Google I/O 2010. May 20, 2010
- talk/rob2010b Origins of Go Concurrency style. Emerging Languages Camp 2010. July 21, 2010.
- talk/rob2010c Public Static Void. OSCON 2010. Jul 22, 2010.
- talk/rob2010d Another Go at Language Design. Aug 27, 2010
- talk/rob2011a Parallelism and Concurrency in Programming Languages. Feb 17, 2011.
- talk/rob2011b Google Go: Concurrency, Type System, Memory Management and GC. Feb 25, 2011.
- talk/rob2011c Lexical Scanning in Go. Aug 30, 2011
- talk/rob2012a Go Concurrency Patterns. Google I/O 2012. Jul 2, 2012.
- talk/rob2012b Why Learn Go?. Sep 12, 2012.
- talk/rob2013a The path to Go 1. Mar 14, 2013.
- talk/rob2013b Go at Google. Apr 13, 2013.
- talk/rob2013c Go Programming with Rob Pike and Andrew Gerrand. Aug 14, 2013.
- talk/rob2013d Concurrency Is Not Parallelism. Oct 20, 2013
- talk/rob2014a Hello Gophers! Gophercon Opening Keynote. GopherCon 2014. Apr 24, 2014
- talk/rob2014b Implementing a bignum calculator. Sydney Go meeup. Nov, 19 2014.
- talk/rob2015a The move from C to Go in the toolchain. GopherFest 2015. Jun 10, 2015.
- talk/rob2015b Go Proverbs. Gopherfest. Nov 18, 2015
- talk/rob2015c Simplicity is Complicated. dotGo 2015. Dec 2, 2015
- talk/rob2016a The Design of the Go Assembler. GopherCon 2016. Aug 18, 2016.
- talk/rob2016b Stacks of Tokens: A study in interfaces. Sydney Go Meetup. September 2016.
- talk/rob2017 Upspin. Gopherfest 2017. Jun 22, 2017.
- talk/rob2018a The History of Unix. Nov 7, 2018.
- talk/rob2018b Go 2 Draft Specifications. Sydney Golang Meetup. Nov 13, 2018
- talk/rob2019a Creating the Go programming language with Rob Pike & Robert Griesemer. Sep 10, 2019.
- talk/rob2019b Rob Pike. A Brief History of Go. Dec 12, 2019.
- talk/rob2020 A Rob Pike Interview. (Date Unclear) 2020.
- Robert Griesemer. (Dr. Robert Griesemer) GitHub, Twitter
- Ken Thompson. (Kenneth Lane Thompson, M. Sc.) (Retired)
- Alma mater: UC Berkeley
- talk/ken1982a The UNIX System: Making Computers More Productive. 1982.
- talk/ken1982b UNIX: Making Computers Easier To Use.
- talk/ken1982c Ken Thompson and Dennis Ritchie Explain UNIX (Bell Labs).
- talk/ken1983 Ken Thompson and Dennis Ritchie. National Medal of Technology Awards. 1996.
- talk/ken2013 Systems Architecture, Design, Engineering, and Verification. Jan 17, 2013.
- talk/ken2019a The Thompson and Ritchie Story. Feb 18, 2019.
- talk/ken2019b Brian Kernighan interviews Ken Thompson. VCF East 2019. May 4, 2019.
- Ian Taylor. (Ian Lance Taylor, B. Sc.) Website, GitHub, Quora
- Alma mater: Yale University
- talk/ian2007 GCC: Current Topics and Future Directions. February 27, 2007.
- talk/ian2018 Transition to Go 2. Gopherpalooza 2018. Oct 24, 2018
- talk/ian2019a Generics in Go. GopherCon 2019. Aug 27, 2019
- talk/ian2020 Go with Ian Lance Taylor. CppCast. Aug 9, 2020.
- Russ Cox. (Dr. Russell Stensby Cox) Website, Blog, GitHub, Twitter, Reddit
- Alma mater: MIT
- paper/russ2008 An Extension-Oriented Compiler. Doctor Dissertation.
- talk/russ2009 The Go Programming Language Promo. Nov 10, 2009.
- talk/russ2012 A Tour of the Go Programming Language. Jun 24, 2012.
- talk/russ2012b A Tour of the Acme Editor. Sep 17, 2012.
- talk/russ2014 Go from C to Go. GopherCon 2014. May 18, 2014
- talk/russ2015 Go, Open Source, Community. GopherCon 2015. Jul 28, 2015.
- talk/russ2016 Codebase Refactoring (with help from Go). Dec 5, 2016.
- talk/russ2017 The Future of Go. GopherCon 2017. Jul 24, 2017.
- talk/russ2018a Dependencies and the future of Go. Apr 19, 2018.
- talk/russ2018b Go and WebAssembly (Wasm). Apr 19, 2018
- talk/russ2018c Opening keynote: Go with Versions. GopherConSG 2018. May 5, 2018
- talk/russ2018d Go 2 Drafts Announcement. Aug 28, 2018.
- talk/russ2019 On the Path to Go 2. GopherCon 2019. Aug 27, 2019.
- talk/russ2020a
go:build
design draft. Jun 30, 2020. - talk/russ2020b
io/fs
draft design. Jul 21, 2020. - talk/russ2020c
//go:embed
draft design. Jul 21, 2020.
Compiler/Runtime Team
Dmitry is not from the Go team but on the dynamic testing tools team from Google. He wrote the scalable goroutine scheduler, many other performance improvements, synchronization primitives, race detector, and blocking profiler that related to the Go runtime. Austin was an intern at Google who worked on the Go project in the early days while pursuing a Ph. D. Later, he joined the Go team after his academic career and work together with Rick for the Go’s concurrent GC. He also worked on the current preemptive scheduler and linker. Now, he is leading the Compiler/Runtime team for Go. Keith and David together focus on the Go’s compiler backend, notably the current SSA backend. Michael is a recent newcomer to the Go team, his work mainly in the runtime memory system such as the refactoring of memory allocator and runtime metrics.
- Dmitry Vyukov. (Дмитрий Вьюков, M. Sc.) Website, GitHub, Twitter
- Alma mater: Bauman Moscow State Technical University
- talk/dmitry2014 Writing a functional, reliable and fast web application in Go. Sep 25, 2014.
- talk/dmitry2015a Chat with Dmitry Vyukov on go-fuzz, golang and IT security. Jul 3, 2015
- talk/dmitry2015b Go Dynamic Tools. GopherCon 2015. Jul 28, 2015.
- talk/dmitry2016 Dmitry Vyukov Interview. Jun 1, 2016.
- talk/dmitry2017 Fuzzing: The New Unit Testing. C++ Russia 2017. May 10, 2017.
- talk/dmitry2018a Fuzzing: new unit testing. GopherCon Russia. Apr 2, 2018.
- talk/dmitry2018b Syzbot and the Tale of Thousand Kernel Bugs. Sep 1, 2018.
- talk/dmitry2019 Go scheduler: Implementing language with lightweight concurrency. Oct 14, 2019.
- talk/dmitry2020 syzkaller: Adventures in Continuous Coverage-guided Kernel Fuzzing. BlueHat IL 2020. Feb 13, 2020.
- Austin Clements. (Dr. Austin T. Clements) GitHub, Scholar
- Alma mater: MIT
- paper/autin2014 The Scalable Commutativity Rule: Designing Scalable Software for Multicore Processors. Doctor Dissertation
- talk/austin2020 Pardon the Interruption: Loop Preemption in Go 1.14. Nov 12, 2020.
- Richard Hudson. (Richard L. Hudson, M. Sc.) GitHub (Retired)
- Alma mater: University of Massachusetts Amherst
- paper/rick Research List
- talk/rick2015 Go GC: Solving the Latency Problem. GopherCon 2015. Jul 8, 2015.
- talk/rick2015b Rick Hudson on Garbage Collection in Go. Dec 21, 2015
- Keith Randall. (Dr. Keith H. Randall.) GitHub
- Alma mater: MIT
- paper/1998keith Cilk: Efficient Multithreaded Computing. Doctor Dissertation.
- talk/keith3016 Inside the Map Implementation. GopherCon 2016. Jul 12, 2016.
- talk/keith3017 Generating Better Machine Code with SSA. GopherCon 2017. Jul 24, 2017.
- David Chase. (Dr. David Chase) Website, Block, GitHub, Twitter, Scholar
- Alma mater: Rice University
- paper/1987david Garbage Collection and Other Optimizations. Doctor Dissertation.
- talk/david2017 All About The Go Compiler. Jul 20, 2017.
- Dan Scales.
- Michael Knyszek. Website, GitHub
- talk/michael2020 Evolving the Go Memory Manager’s RAM and CPU Efficiency. Nov 11, 2020
- Than McIntosh. GitHub
- Cherry Zhang. GitHub
- Andrew Gerrand. GitHub, Twitter
- Brad Fitzpatrick. Website, GitHub, Twitter
- talk/brad2010 Writing zippy Android apps. Google I/O 2010. May 27, 2010.
- talk/brad2011 Palestra Brad FitzPatrick. Perl Workshop. Parte 1. May 12, 2011.
- talk/brad2012 Behind the Scenes at LiveJournal: Scaling Storytime. Brad Fitzpatrick. May 21, 2012.
- talk/brad2013a Software I’m excited about. dotScale 2013. Jul 30, 2013.
- talk/brad2013b LiveJournal’s Moscow office. Brad Fitzpatrick. Dec 15, 2013.
- talk/brad2014a Camlistore. Go meetup. Jan 2014.
- talk/brad2014b Camlistore & The Standard Library. GopherCon 2014. May 18, 2014.
- talk/brad2014c The State of the Gopher. dotGo 2014. October 10, 2014.
- talk/brad2014d Interview. dotGo 2014. Nov 6, 2014.
- talk/brad2015a Hacking with Andrew and Brad: an HTTP/2 client. Feb 25, 2015.
- talk/brad2015b HTTP/2 and Go. London Go Gathering 2015. Mar 4, 2015.
- talk/brad2015c HTTP/2 for Go. Go Devroom FOSDEM 2015. Mar 4, 2015.
- talk/brad2015d The state of the Gopher. Munich Gophers. Apr 18, 2015
- talk/brad2015e The Go Language. devoxx poland 2015. June, 2015
- talk/brad2015f Hacking with Andrew and Brad: tip.golang.org. Jan 8, 2015.
- talk/brad2015g Lightning Talk: HTTP/2 in Go. GopherCon 2015. Aug 19, 2015.
- talk/brad2015h Profiling & Optimizing in Go. Aug 27, 2015.
- talk/brad2016a Introducing Go 1.6: asymptotically approaching boring. Gophercon India 2016. Mar 29, 2016.
- talk/brad2016b Lightning Talk: My video & security system. GopherCon 2016. July, 2016.
- talk/brad2016c Go 1.7. Seattle Go Meetup. Aug 25, 2016.
- talk/brad2016d The Go Open Source Project’s Innards. GothamGo 2016. Dec 15, 2016.
- talk/brad2017 Half my life spent in open source. May 19, 2017.
- talk/brad2018a Go: looking back and looking forward. Apr 2, 2018.
- talk/brad2018b Go 1 11 and beyond. Aug 26, 2018.
- talk/brad2018c Lightning Talk: The nuclear option, go test -run=InQemu. GopherCon 2018. Sep 11, 2018.
- talk/brad2019 Brad Fitzpatrick likes Go better than C, C++, Rust, Perl, Python, Ruby, JavaScript and Java. Nov 28, 2019.
- Bryan C. Mills. GitHub
- talk/bryan2017 Lightning Talk: An overview of sync.Map. GopherCon 2017. Jul 24, 2017.
- talk/bryan2018 Rethinking Classical Concurrency Patterns. GopherCon 2018. Sep 14, 2018
- Steve Francia. Website GitHub, Twitter.
- talk/steve2019a What Should A Modern Practical Programming Language Look Like. Landing Festival. April 4, 2019.
- talk/steve2019b The Legacy Of Go. Go Lab. Oct 22, 2019.
- Jonathan Amsterdam.
- Daniel Martí. Website, GitHub, Twitter
- Nigel Tao. GitHub, Twitter
- Filippo Valsorda. GitHub,
- Michael Matloob. GitHub, Twitter
- Jay Conrod. Website, Twitter
- Dave Cheney. Website, GitHub, Twitter
- Sam Boyer. GitHub, Twitter
more people and talks should be added…
Group Interviews
Timeline
A timeline helps you identify the point in time about a document that is reflected in Go versions.
Version | Release Date |
---|---|
Go 1 | 2012.03.28 |
Go 1.1 | 2013.05.13 |
Go 1.2 | 2013.12.01 |
Go 1.3 | 2014.06.18 |
Go 1.4 | 2014.12.10 |
Go 1.5 | 2015.08.19 |
Go 1.6 | 2016.02.17 |
Go 1.7 | 2016.08.15 |
Go 1.8 | 2017.02.16 |
Go 1.9 | 2017.08.24 |
Go 1.10 | 2018.02.16 |
Go 1.11 | 2018.08.24 |
Go 1.12 | 2019.02.25 |
Go 1.13 | 2019.09.03 |
Go 1.14 | 2020.02.25 |
Go 1.15 | 2020.08.11 |
Go 1.16 | 2021.02.16 |
The historical release notes may helpful for general information:
Language Design
Misc
- design/go0initial Rob Pike, Robert Griesemer, Ken Thompson. The Go Annotated Specification. Mar 3, 2008.
- design/go0spec0 The Go Programming Language. Language Specification (March 7, 2008)
- design/go0semicolon Rob Pike. Semicolons in Go. Dec 10, 2009.
- design/go11func Russ Cox. Go 1.1 Function Calls. February 2013
- design/go11return Russ Cox. Go “Return at End of Function” Requirements. March 2013
- design/go12nil Russ Cox. Go 1.2 Field Selectors and Nil Checks. July 2013.
- doc/go13todo Go 1.3 “To Do” List
- doc/goatgoogle Rob Pike. Go at Google — Language Semantics. October 25, 2012.
- doc/makego Andrew Gerrand. How Go was Made. 9 July 2015.
- discuss/go1preview Russ Cox. Go 1 Preview.
- design/overlapping-interfaces Robert Griesemer. Proposal: Permit embedding of interfaces with overlapping method sets. 2019-10-16
- issue/6977 spec: allow embedding overlapping interfaces
- design/struct-conversion Robert Griesemer. Proposal: Ignore tags in struct type conversions. June 16, 2016.
- issue/16085 Proposal: Ignore tags in struct type conversions
- design/go2trans Ian Lance Taylor. Proposal: Go 2 transition. October 15, 2018
- design/signed-int-shift Robert Griesemer. Proposal: Permit Signed Integers as Shift Counts for Go 2. January 17, 2019
- design/number-literal Russ Cox, Robert Griesemer. Proposal: Go 2 Number Literal Changes. March 6, 2019
- issue/12711 proposal: different octal base literal representation
- issue/19308 proposal: spec: binary integer literals
- issue/28493 proposal: permit blank (_) separator in integer number literals
- issue/29008 proposal: Go 2: hexadecimal floats
- issue/33502 proposal: review meeting minutes
- issue/33892 proposal: Go 2 review meeting minutes
- issue/19623 proposal: spec: change int to be arbitrary precision
- issue/19367 unsafe: add Slice(ptr *T, len anyIntegerType) []T
- issue/40481 unsafe: add Add function
Slice (1.2)
Package Management (1.4, 1.5, 1.7)
Type alias (1.9)
- design/type-alias Russ Cox, Robert Griesemer. Proposal: Type Aliases. December 16, 2016
- talk/type-alias GopherCon 2016 — Lightning Talk: Robert Griesemer — Alias Declarations for Go, A proposal. Oct 9, 2016
- issue/16339 proposal: Alias declarations for Go
- issue/18130 all: support gradual code repair while moving a type between packages
- talk/refactor-video Russ Cox. Codebase Refactoring (with help from Go). GothamGo 2016. November 18, 2016.
- doc/refactor Russ Cox. Codebase Refactoring (with help from Go).
Defer (1.14)
- design/open-defer Dan Scales, Keith Randall, and Austin Clements. Proposal: Low-cost defers through inline code, and extra funcdata to manage the panic case. 2019-09-23
- Unsolved
defer recover()
edge cases.- issue/10458 spec: panicking corner-case semantics
- issue/23531 spec: recover() in nested defer
- issue/26275 runtime: document the behaviour of Caller and Callers when used in deferred functions
- issue/34530 spec: clarify when calling recover stops a panic
- cl/189377 spec: specify the behavior of recover and recursive panics in more detail
Error values (1.13)
- doc/err2011 Andrew Gerrand. Error handling in Go. July 2011.
- doc/err-values Rob Pike. Errors are values. January 2015.
- doc/err-philosophy Dave Cheney. My philosophy for error handling. April 2016.
- doc/err-gracefully Dave Cheney. Don’t just check errors, handle them gracefully. April 2016.
- doc/err-stacktrace Dave Cheney. Stack traces and the errors package. June, 12 2016.
- doc/err-upspin Rob Pike. Error handling in Upspin. December 06, 2017.
- doc/err-work Damien Neil and Jonathan Amsterdam. Working with Errors in Go 1.13. October 17, 2019.
- design/err-handling-overview Russ Cox. Error Handling — Problem Overview.
- doc/err-value-faq Jonathan Amsterdam and Bryan C. Mills. Error Values: Frequently Asked Questions. August 2019.
- design/err-handle-check Marcel van Lohuizen. Error Handling — Draft Design. August 27, 2018.
- design/err-try Robert Griesemer. Proposal: A built-in Go error check function, «try». 2019-06-12
- issue/32437 Proposal: A built-in Go error check function, «try». Decision response.
- design/err-inspect Jonathan Amsterdam, Damien Neil. Error Inspection — Draft Design. August 27, 2018.
- design/err-values-overview Russ Cox. Error Values — Problem Overview. August 27, 2018.
- design/error-values Jonathan Amsterdam, Russ Cox, Marcel van Lohuizen, Damien Neil. Proposal: Go 2 Error Inspection. January 25, 2019
- issue/29934 Jonathan Amsterdam. proposal: Go 2 error values. Jan 25, 2019.
- issue/29934-decision Damien Neil. Go 1.13 lunch decision about error values. May 6, 2019.
- issue/29934-russ Russ Cox. Response, Response regarding «proposal: Go 2 error values». May 7, 2019.
- design/err-print Marcel van Lohuizen. Error Printing — Draft Design. August 27, 2018.
- issue/40432 language: Go 2: error handling meta issue
- issue/40776 proposal: dynamic ignored error detector
- issue/41198 proposal: errors: add ErrUnimplemented as standard way for interface method to fail.
Channel/Select
- design/lockfree-channels Dmitry Vyukov. Go channels on steroids. Jan 28, 2014
- issue/8898 runtime: special case timer channels
- issue/37196 time: make Timer/Ticker channels not receivable with old values after Stop or Reset returns
- issue/8903 runtime: make chan-based generators faster.
- issue/21806 fairness in select statement.
- issue/40410 runtime: trim unnecessary fields from scase
- issue/40641 runtime: race between stack shrinking and channel send/recv leads to bad sudog values
- issue/37350 reflect: Select panics if array length greater than 1<<16
Generics
- doc/generics-discuss Summary of Go Generics Discussions
- doc/generics-dilemma Russ Cox. The Generic Dilemma. December 3, 2009.
- design/type-functions Ian Lance Taylor. Type Functions. June 2010.
- design/generalized-types Ian Lance Taylor. Generalized Types. March 2011.
- design/code-gen Russ Cox. Alternatives to Dynamic Code Generation in Go. September 2012.
- design/generalized-types2 Ian Lance Taylor. Generalized Types In Go. October 2013.
- design/type-parameters Ian Lance Taylor. Type Parameters in Go. December 2013.
- design/compile-time-function Bryan C. Mills. Compile-time Functions and First Class Types. September 2016.
- design/should-generics Ian Lance Taylor. Go should have generics. January 2011.
- design/should-generics2 Ian Lance Taylor. Go should have generics. Updated: April 2016.
- issue/15292 proposal: spec: generic programming facilities
- design/generics-overview Russ Cox. Generics — Problem Overview. August 27, 2018.
- design/contracts Ian Lance Taylor, Robert Griesemer. Contracts — Draft Design. August 27, 2018, Updated: July 31, 2019.
- design/type-parameters2 Ian Lance Taylor, Robert Griesemer. Type Parameters — Draft Design. June 16, 2020, Updated: August 28, 2020.
- discuss/generics-parenthesis Robert. Generics and parenthesis.
- issue/33232 proposal: Go 2: add alias for interface {} as any
- discuss/generics-move Ian, Moving forward with the generics design.
- discuss/generics-implementation Implementing Generics
- design/generics-implementation-stenciling Generics implementation — Stenciling
- design/generics-implementation-dictionaries Generics implementation — Dictionaries
- issue/43651 proposal: spec: add generic programming using type parameters
- design/type-parameters3 Type Parameters Proposal
- issue/45346 proposal: spec: generics: use type sets to remove type keyword in constraints
- issue/46477 proposal: spec: generics: type parameters on aliases
- Standard packages using generics
- issue/45458 proposal: constraints: new package to define standard type parameter constraints
- discuss/47319 proposal: constraints: new package to define standard type parameter constraints (discussion)
- issue/45955 proposal: slices: new package to provide generic slice functions
- discuss/47203 proposal: slices: new package to provide generic slice functions (discussion)
- discuss/47331 proposal: container/set: new package to provide a generic set type (discussion)
- discuss/47330 proposal: maps: new package to provide generic map functions (discussion)
Compiler
- code/gc0initial Ken Thompson. Go0 compiler initial version. 28 Mar 2008.
- code/6g Rob Pike. the first complete Go0 compiler. 4 Jun 2008.
- design/go12symtab Russ Cox. Go 1.2 Runtime Symbol Information. July 2013.
- design/go13compiler Russ Cox. Go 1.3+ Compiler Overhaul. December 2013
- design/go14generate Rob Pike. Go generate: A Proposal
- design/dev.cc Russ Cox. dev.cc branch plan. Nov 2014
- design/go15bootstrap Russ Cox. Go 1.5 Bootstrap Plan. January 2015.
- doc/escape-analysis Dmitry Vyukov. Go Escape Analysis Flaws. Feb 10, 2015.
- design/execmodes Ian Lance Taylor. Go Execution Modes. August, 2014 (updated January 2016)
- design/go17ssa Keith Randall. New SSA Backend for the Go Compiler. 2/10/2015.
- doc/compiler-optimization Compiler And Runtime Optimizations.
- issue/6853 all: binaries too big and growing.
- design/go19inlining David Lazar, Austin Clements. Proposal: Mid-stack inlining in the Go compiler.
- design/dwarf-inlining Than McIntosh. Proposal: emit DWARF inlining info in the Go compiler. 2017-10-23.
- issue/23109 cmd/compile: rewrite escape analysis.
- issue/27167 cmd/compile: rename a bunch of things
- GOEXPERIMENT=checkptr
- issue/37121 runtime: unaligned jumps causing performance regression on Intel
- issue/16798 proposal: cmd/compile: add tail call optimization for self-recursion only. (declined)
- issue/22624 proposal: Go 2: add become statement to support tail calls (declined)
- design/64align Dan Scales. Proposal: Make 64-bit fields be 64-bit aligned on 32-bit systems, add //go:packed, //go:align directives. 2020-06-08.
- issue/599 cmd/compile: make 64-bit fields 64-bit aligned on 32-bit systems
- issue/36606 proposal: cmd/compile: make 64-bit fields be 64-bit aligned on 32-bit systems, add //go:packed directive on structs
- talk/gccgo Brief overview of gccgo, «the other» Go compiler. Aug 6, 2015.]
Linker
The Go Linker was written by Ken Thompson. Russ led a few more overhaul in Go 1.3. Austin led a rework to the linker together with Keith, Than, Cheery and many other brilliant brains, which was landed in Go 1.15 and Go 1.16.
Debugger
Race Detector
- issue/42598 runtime: apparent false-positive race report for a buffered channel after CL 220419
Tracer
Lock Analysis
- issue/38029 x/build: linux-amd64-staticlockranking consistently failing
- cl/192704 runtime: lock operation logging support
- cl/207348 runtime: release timersLock while running timer
- cl/207846 runtime: avoid potential deadlock when tracing memory code
- cl/207619 runtime: static lock ranking for the runtime (enabled by GOEXPERIMENT)
- cl/222925 cmd/go: define a build tag for any GOEXPERIMENT which is enabled
- cl/228417 runtime: incorporate Gscan acquire/release into lock ranking order
- cl/229480 runtime: added several new lock-rank partial order edges
- cl/231463 runtime: add one extra lock ranking partial edge
- cl/233599 runtime: add a lock partial order edge (assistQueue -> mspanSpecial)
- cl/236137 runtime: add three new partial orders for lock ranking
- issue/40677 runtime: lock held checking
Builder
Modules
- design/go-dep Go Packaging Proposal Process
- design/go-dep2 Dependency Management Tool
- doc/go-dep Sam Boyer. The Saga of Go Dependency Management. Dec 13, 201
- talk/go-dep GopherCon 2017: Sam Boyer — The New Era of Go Package Management. Jul 24, 2017
- talk/go-dep-design dotGo 2017 — sam boyer — The Functional Design of Dep. Dec 8, 2017
- discuss/go-dep Building Predictability into Your Pipeline :: Russ Cox; Jess Frazelle, Sam Boyer, Pete Garcin. Feb 22, 2018
- design/vgo Russ Cox. Proposal: Versioned Go Modules. March 20, 2018.
- design/sumdb Russ Cox, Filippo Valsorda. Proposal: Secure the Public Go Module Ecosystem. April 24, 2019.
- issue/25530 proposal: cmd/go: secure releases with transparency log
- issue/23966 why go.mod has its own bespoke syntax?
- design/lazy-gomod Bryan C. Mills. Proposal: Lazy Module Loading. 2020-02-20
- issue/45713 proposal: cmd/go: add a workspace mode
gopls
- design/gopls-workspace Heschi Kreinick, Rebecca Stambler. Proposal: Multi-project gopls workspaces. Mar 9, 2020.
Testing
- design/subtests Marcel van Lohuizen. testing: programmatic sub-test and sub-benchmark support. September 2, 2015.
- issue/12166 proposal: testing: programmatic sub-test and sub-benchmark support
- design/gotest-bench Russ Cox, Austin Clements. Proposal: Go Benchmark Data Format. February 2016.
- issue/14313 cmd/go: decide, document standard benchmark data format
- issue/20875 testing: consider calling ReadMemStats less during benchmarking
- issue/27217 testing: tiny benchmark with StopTimer runs forever
- issue/41637 testing: benchmark iteration reports incorrectly
- issue/41641 testing: inconsistent benchmark measurements when interrupts timer
- design/gotest-json Nodir Turakulov. Proposal: -json flag in go test. 2016-09-14.
- design/testing-helper Caleb Spare. Proposal: testing: better support test helper functions with TB.Helper. 2016-12-27
- issue/4899 testing: add t.Helper to make file:line results more useful
- design/fuzzing Katie Hockman. Design Draft: First Class Fuzzing
Runtime Core
Scheduler
- paper/work-steal Robert D. Blumofe and Charles E. Leiserson. 1999. Scheduling multithreaded computations by work stealing. J. ACM 46, 5 (September 1999), 720-748.
- cl/sched-m-1 Russ Cox, Clean up scheduler. Aug 5, 2008.
- cl/sched-m-n things are much better now, Nov 11, 2009.
- design/go11sched Dmitry Vyukov. Scalable Go Scheduler Design Doc, 2012
- design/sched-preempt-dmitry Dmitry Vyukov. Go Preemptive Scheduler Design Doc, 2013
- design/sched-numa Dmitry Vyukov, NUMA-aware scheduler for Go. Sep 2014.
- design/go15gomaxprocs Russ Cox. Go 1.5 GOMAXPROCS Default. May 2015.
- doc/go17sched Ian Lance Taylor. How does the golang scheduler work? July 16, 2016.
- design/sched-preempt-austin Austin Clements. Proposal: Non-cooperative goroutine preemption. Jan 2019.
- cl/43050 cmd/compile: loop preemption with fault branch on amd64. May 09, 2019.
- issue/10958 runtime: tight loops should be preemptible
- issue/24543 runtime: non-cooperative goroutine preemption
- issue/36365 runtime: clean up async preemption loose ends
- issue/14592 runtime: let idle OS threads exit
- issue/18237 runtime: scheduler is slow when goroutines are frequently woken
- issue/20395 runtime: terminate locked OS thread if its goroutine exits
- issue/20458 proposal: runtime: pair LockOSThread, UnlockOSThread calls
- issue/21827 runtime: big performance penalty with runtime.LockOSThread
- issue/27345 runtime: use parent goroutine’s stack for new goroutines
- issue/28808 runtime: scheduler work stealing slow for high GOMAXPROCS
- issue/32113 runtime: optimization to reduce P churn.
- issue/44313 runtime: stopped Ms can’t become dedicated or fractional GC workers
Execution Stack
Memory Allocator
A quick history about the Go’s memory allocator: Russ Cox first implements
the memory allocator based on tcmalloc
for Go 1, mcache
is cached on M.
Then he revised the allocator to allow user code to use 16GB memory and later allows 128GB. However, the allocator (including scavenger) was
suffered from massive lock contentions and does not scale. After Dmitry’s scalable runtime
scheduler, the allocator can allocate directly from P (with much less)
lock contentions. In the meantime, the scavenger is migrated from an independent
thread into the system monitor thread. Now, Michael is actively working on
improving the memory allocator’s scalability, such as migrating scavenger
to user threads, bitmap-based page allocator, scalable mcentral.
- doc/tcmalloc Sanjay Ghemawat, Paul Menage. TCMalloc : Thread-Caching Malloc. Google Inc., 2009
- design/go113scavenge Michael Knyszek. Proposal: Smarter Scavenging. 2019-05-09.
- issue/30333 runtime: smarter scavenging
- issue/32012 runtime: background scavenger is overzealous with small heaps
- issue/31966 runtime: background scavenger can delay deadlock detection significantly
- issue/34047 runtime: potential deadlock cycle caused by scavenge.lock
- issue/34048 runtime: scavenger pacing fails to account for fragmentation
- issue/35788 runtime: scavenger not as effective as in previous releases
- issue/36521 runtime: performance degradation in go 1.12
- issue/36603 runtime: sysUsed often called on non-scavenged memory
- design/go114pagealloc Michael Knyszek, Austin Clements. Proposal: Scaling the Go page allocator. 2019-10-18.
- issue/35112 runtime: make the page allocator scale
- cl/200439 runtime: place lower limit on trigger ratio
- issue/8885 runtime: consider adding 24-byte size class.
- issue/37487 runtime: improve mcentral scalability
- cl/221182 runtime: add new mcentral implementation
- issue/18155 runtime: latency in sweep assists when there’s no garbage
- issue/19112 runtime: deadlock involving gcControllerState.enlistWorker
- issue/23687 runtime: use MADV_FREE on linux as well
- cl/135395 runtime: use MADV_FREE on Linux if available
- issue/29707 cmd/trace: failed to parse trace: no consistent ordering of events possible
- issue/35954 runtime: handle hitting the top of the address space in the allocator more gracefully
- issue/37927 runtime: GC pacing exhibits strange behavior with a low GOGC
- issue/38130 runtime: incorrect sanity checks in the page allocator
- issue/38404 runtime: STW GC stops working on arm64/mips64le
- issue/38605 runtime: pageAlloc.allocToCache updates pageAlloc.searchAddr in an invalid way
- issue/38617 runtime: scavenger freezes up in Go 1.14 in Windows due to coarse time granularity
- issue/38966 runtime: aix-ppc64 builder is failing with «bad prune», «addr range base and limit are not in the same memory segment» fatal errors
- issue/39128 runtime: linux-mips-rtrk builder consistently failing with «bad prune» as of CL 233497
- issue/40191 runtime: pageAlloc.searchAddr may point to unmapped memory in discontiguous heaps, violating its invariant
- issue/40457 runtime: runqputbatch does not protect its call to globrunqputbatch
- issue/40641 runtime: race between stack shrinking and channel send/recv leads to bad sudog values
- issue/42330 runtime: default to MADV_DONTNEED on Linux
- cl/267100 runtime: default to MADV_DONTNEED on Linux
Garbage Collector
- paper/on-the-fly-gc Edsger W. Dijkstra, Leslie Lamport, A. J. Martin, C. S. Scholten, and E. F. M. Steffens. 1978. On-the-fly garbage collection: An exercise in cooperation. Commun. ACM 21, 11 (November 1978), 966–975.
- paper/yuasa-barrier T. Yuasa. 1990. Real-time garbage collection on general-purpose machines. J. Syst. Softw. 11, 3 (March 1990), 181-198.
- design/go13gc Dmitry Vyukov. Simpler and faster GC for Go. July 16, 2014
- design/go14gc Richard L. Hudson. Go 1.4+ Garbage Collection (GC) Plan and Roadmap. August 6, 2014.
- design/go15gcpacing Austin Clements. Go 1.5 concurrent garbage collector pacing. 2015-03-10.
- discuss/gcpacing Austin Clements et al. Discussion of «Proposal: Garbage collector pacing». March 10, 2015.
- issue/11970 runtime: replace GC coordinator with state machine
- design/sweep-free-alloc Austin Clements. Proposal: Dense mark bits and sweep-free allocation. Sep 30, 2015.
- issue/12800 runtime: replace free list with direct bitmap allocation
- design/decentralized-gc Austin Clements. Proposal: Decentralized GC coordination. October 25, 2015.
- issue/12967 runtime: shrinkstack during mark termination significantly increases GC STW time
- issue/14951 runtime: mutator assists are over-aggressive, especially at high GOGC
- design/eliminate-rescan Austin Clements, Rick Hudson. Eliminate STW stack re-scanning. October 21, 2016.
- design/concurrent-rescan Austin Clements, Rick Hudson. Proposal: Concurrent stack re-scanning. Oct 18, 2016.
- issue/17505 runtime: perform concurrent stack re-scanning
- design/soft-heap-limit Austin Clements. Proposal: Separate soft and hard heap size goal. October 21, 2017.
- issue/22460 runtime: optimize write barrier
- design/roc Request Oriented Collector (ROC) Algorithm
- doc/ismm-gc Rick Hudson. Getting to Go: The Journey of Go’s Garbage Collector. 12 July 2018.
- discuss/ismm-gc Garbage Collection Slides and Transcript now available
- design/simplify-mark-termination Austin Clements. Proposal: Simplify mark termination and eliminate mark 2. Aug 9, 2018.
- issue/26903 runtime: simplify mark termination and eliminate mark 2
- design/gcscan Proposal: GC scanning of stacks
- issue/22350 cmd/compile: compiler can unexpectedly preserve memory,
- issue/27993 runtime: error message: P has cached GC work at end of mark termination
- issue/37116 runtime: 10ms-26ms latency from GC in go1.14rc1, possibly due to ‘GC (idle)’ work
- issue/42430 runtime: GC pacer problems meta-issue
- issue/39983 runtime: idle GC interferes with auto-scaling
- issue/17969 runtime: aggressive GC completion is disruptive to co-tenants
- issue/14812 runtime: GC causes latency spikes
- issue/40460 runtime: goroutines may allocate beyond the hard heap goal
- issue/29696 proposal: runtime: add way for applications to respond to GC backpressure
- issue/23044 proposal: runtime: add a mechanism for specifying a minimum target heap size
- issue/42642 runtime: multi-ms sweep termination pauses (second edition)
- issue/44163 runtime: remove idle GC workers
- issue/44167 runtime: GC pacer redesign
- issue/44309 proposal: runtime/debug: user-configurable memory target
- issue/45894 runtime: mark termination is slow to restart mutator
- issue/45315 runtime: runtime.GC can return without finishing sweep
Statistics
Memory model
The Go memory model consists the following parts:
Memory order regarding atomic operations
Memory order regarding the
sync
package APIsMemory order regarding runtime mechanism (i.e. Object finalizer)
doc/refmem Rob Pike and Russ Cox. The Go Memory Model. February 21, 2009.
issue/4947 cmd/cc: atomic intrinsics
issue/5045 doc: define how sync/atomic interacts with memory model
issue/7948 doc: define how sync interacts with memory model
issue/9442 doc: define how finalizers interact with memory model
issue/33815 doc/go_mem: «hello, world» will not always be printed twice
cl/75130045 doc: allow buffered channel as semaphore without initialization
doc/gomem Russ Cox. Go’s Memory Model. February 25, 2016.
doc/go2017russ Russ Cox. My Go Resolutions for 2017: Memory model. January 18, 2017.
doc/atomic-bug Package atomic
discuss/atomic-mem-order specify the memory order guarantee provided by atomic Load/Store
issue/37355 runtime/race: running with -race misses races (mismatch with memory model)
- cl/220419 runtime: swap the order of raceacquire() and racerelease
- issue/42598 runtime: apparent false-positive race report for a buffered channel after CL 220419
- cl/271987 runtime: check channel’s elemsize before calling race detector
- [paper/fava2020fix] Fava, Daniel Schnetzer. «Finding and Fixing a Mismatch Between the Go Memory Model and Data-Race Detector.» International Conference on Software Engineering and Formal Methods. Springer, Cham, 2020.
doc/mm Russ Cox. Memory Models. June, 2021.
- doc/hwmm Russ Cox. Hardware Memory Models. June 29, 2021.
- doc/plmm Russ Cox. Programming Language Memory Models. July 6, 2021.
- doc/gomm Russ Cox. Updating the Go Memory Model. July 12, 2021.
- discuss/47141 Updating the Go memory model.
ABI
- design/cgo-pointers Ian Lance Taylor. Proposal: Rules for passing pointers between Go and C. October, 2015
- issue/12416 cmd/cgo: specify rules for passing pointers between Go and C
- design/internal-abi Austin Clements. Proposal: Create an undefined internal calling convention. 2019-01-14.
- issue/27539 proposal: runtime: make the ABI undefined as a step toward changing it.
- issue/31193 cmd/compile, runtime: reduce function prologue overhead
- design/register-call Austin Clements, with input from Cherry Zhang, Michael Knyszek, Martin Möhrmann, Michael Pratt, David Chase, Keith Randall, Dan Scales, and Ian Lance Taylor. Proposal: Register-based Go calling convention. 2020-08-10.
- issue/18597 proposal: cmd/compile: define register-based calling convention
- issue/40724 proposal: switch to a register-based calling convention for Go functions
- cl/266638 reflect,runtime: use internal ABI for selected ASM routines, attempt 2
- cl/259445 cmd/compile,cmd/link: initial support for ABI wrappers
Misc
- issue/20135 runtime: shrink map as elements are deleted
Standard Library
syscall
os, io, io/fs, embed
In Go 1.16, tons of major rework and improvements surround the new os/fs
package.
- design/draft-iofs Russ Cox, Rob Pike. File System Interfaces for Go — Draft Design. July 2020.
- issue/13473 proposal: os: Stdin, Stdout and Stderr should be interfaces
- issue/14106 proposal: os: File should be an interface
- issue/19660 proposal: io/ioutil: rename to io/fileio or similar
- issue/40025 proposal: io/ioutil: move Discard, NopCloser, ReadAll to io
- issue/42027 proposal: path/filepath: add WalkDir (Walk using DirEntry)
- issue/41190 io/fs: add file system interfaces
- issue/41467 os: add ReadDir method for lightweight directory reading
- issue/41974 proposal: io/fs, filepath: add more efficient Walk alternative
- issue/42026 proposal: os: add ReadDir, ReadFile, WriteFile, CreateTemp, MkdirTemp & deprecate io/ioutil
- issue/43223 proposal: io/fs, net/http: define interface for automatic ETag serving
- design/go116embed Embedded files — Russ & Braid
- issue/41191 embed, cmd/go: add support for embedded files
- issue/42321 embed: warn about dotfiles in embed.FS documentation
- issue/42328 proposal: cmd/go: avoid surprising inclusion of «hidden» files when using //go:embed
- issue/43216 proposal: embed: remove support for embedding directives on local variables
- issue/43217 proposal: embed: define String and Bytes type aliases that must be used with //go:embed
- issue/43218 embed: resolve string, []byte issues
- issue/44166 io/fs,os: fs.ReadDir with an os.DirFS can produce invalid paths
- issue/42322 io/fs: add func Sub(fsys FS, dir string) FS
go/*
- doc/gotypes Alan Donovan. go/types: The Go Type Checker.
- talk/gotypes Alan Donovan. Using go/types for Code Comprehension and Refactoring Tools. October 2, 2015.
- design/modular-interface Alan Donovan. Proposal: a common interface for modular static analyses for Go. 9 Sep 2018
- cl/134935 go/analysis: a new API for analysis tools
sync
- design/percpu-sharded Sanjay Menakuru. Proposal: percpu.Sharded, an API for reducing cache contention. Jun 12, 2018.
- issue/37142 sync: shrink types in sync package
Map
- issue/21031 sync: reduce pointer overhead in Map
- issue/21032 sync: reduce (*Map).Load penalty for Stores with new keys
- issue/21035 sync: reduce contention between Map operations with new-but-disjoint keys
- issue/37033 runtime: provide centralized facility for managing (c)go pointer handles
Pool
- discuss/add-pool gc-aware pool draining policy
- issue/4720 sync: add Pool type. Jan 28, 2013.
- cl/46010043 sync: scalable Pool. Jan 24, 2014.
- cl/86020043 sync: less agressive local caching in Pool. Apr 14, 2014.
- cl/162980043 sync: release Pool memory during second and later GCs. Oct 22, 2014.
- issue/8979 sync: Pool does not release memory on GC
- issue/22331 runtime: clearpools causes excessive STW1 time
- issue/22950 sync: avoid clearing the full Pool on every GC.
- cl/166960 sync: use lock-free structure for Pool stealing.
- cl/166961 166961: sync: smooth out Pool behavior over GC with a victim cache.
- issue/24479 sync: eliminate global Mutex in Pool operations
Mutex, RWMutex
- cl/4631059 runtime: replace Semacquire/Semrelease implementation.
- issue/9201 proposal: sync: prohibit unlocking mutex in a different goroutine
- issue/13086 runtime: fall back to fair locks after repeated sleep-acquire failures.
- issue/17973 sync: RWMutex scales poorly with CPU count
- cl/215361 sync: Implement a version of RWMutex that can avoid cache contention
Groups
- cl/134395 errgroup: rethink concurrency patterns
- cl/131815 errgroup: handle runtime.Goexit from child goroutines
- issue/15758 testing: complain loudly during concurrent use of T.FatalX and T.SkipX
- issue/25448 proposal: promote panic(nil) to non-nil panic value
atomic
- issue/8739 runtime,sync/atomic: unify API for runtime/internal/atomic and sync/atomic
- issue/20164 proposal: atomic: add (*Value).Swap
- discuss/atomic-value
- issue/36606 proposal: cmd/compile: make 64-bit fields be 64-bit aligned on 32-bit systems, add //go:packed directive on structs
- issue/37262 runtime: can’t atomic access of first word of tiny-allocated struct on 32-bit architecture
time
- design/monotonic-time Russ Cox. Proposal: Monotonic Elapsed Time Measurements in Go. January 26, 2017.
- issue/12914 time: use monotonic clock to measure elapsed time
- Scalable Timer
- cl/34784 runtime: improve timers scalability on multi-CPU systems
- issue/6239 runtime: make timers faster.
- issue/15133 runtime: timer doesn’t scale on multi-CPU systems with a lot of timers
- issue/27707 time: excessive CPU usage when using Ticker and Sleep.
- Followup latency issues
- issue/18023 runtime: unexpectedly large slowdown with runtime.LockOSThread
- issue/25471 time: Sleep requires ~7 syscalls
- issue/38070 runtime: timer self-deadlock due to preemption point
- issue/36298 net: 1.14 performance regression on mac
- issue/38860 runtime: CPU bound goroutines cause unnecessary timer latency
- cl/216198 runtime: add goroutines returned by poller to local run queue
- cl/232199 runtime: steal timers from running P’s
- cl/232298 runtime: reduce timer latency
- issue/44343 runtime: time.Sleep takes more time than expected
- issue/44868 time, runtime: zero duration timer takes 2 minutes to fire
context
- issue/8082 proposal: spec: represent interfaces by their definition and not by package and name
- issue/14660 proposal: context: new package for standard library
- issue/16209 Proposal: relaxed rules for assignability with differently-named but identical interfaces
- issue/20280 proposal: io: add Context parameter to Reader, etc.
- issue/21355 proposal: Replace Context with goroutine-local storage
- issue/24050 testing: test with child process sometimes hangs on 1.10; -timeout not respected
- [issue/27982] proposal: Go 2: bake a cooperative goroutine cancellation mechanism into the language
- issue/28342 proposal: Go 2: update context package for Go 2
- issue/29011 proposal: Go 2: use structured concurrency
- doc/context-go-away Michal Štrba. Context should go away for Go 2. 2017/08/06
- doc/context Go Concurrency Patterns: Context.
- doc/context-isnt-for-cancellation Dave Cheney. Context isn’t for cancellation. August 20, 2017.
- issue/42564 context: cancelCtx exclusive lock causes extreme contention
encoding
- design/go12encoding Russ Cox. Go 1.2 encoding.TextMarshaler and TextUnmarshaler. July 2013.
- design/go12xml Russ Cox. Go 1.2 xml.Marshaler and Unmarshaler. July 2013.
- design/natural-xml Sam Whited. Proposal: Natural XML. 2016-09-27
- issue/13504 encoding/xml: add generic representation of XML data
- design/zip Russ Cox. Proposal: Zip-based Go package archives. February 2016
- issue/14386 proposal: use zip format inside .a and .o files
- design/xmlstream Sam Whited. Proposal: XML Stream. 2017-03-09
- issue/19480 encoding/xml: add decode from TokenReader, to enable stream transformers
- design/raw-xml Sam Whited. Proposal: Raw XML Token. 2018-09-01
image, x/image
The following issues are surrounding by the color management of the image
standard library.
At the moment, Go’s image
library doesn’t read or write meta information from an image in
the encoding or decoding phase. Therefore the color information could go wrong while processing
an image such as scaling in a non-linear sRGB space. A universal solution is to design image
metadata APIs to aware the color profile in an encoded image file.
- issue/11420 x/image/draw: color space-correct interpolation
- issue/20613 image/png: don’t ignore PNG gAMA chunk
- issue/27830 proposal: image: decoding options
- cl/253497 x/image/draw: gamma corrected non linear interpolation
- issue/37188 image/color: documentation doesn’t include links to relevant color theory resources
- issue/33457 proposal: image: add generic metadata support for jpeg, gif, png
- issue/44808 image, image/draw: add interfaces for using RGBA64 directly
- issue/46395 image/draw: increase performances by applying special case if mask is *image.Alpha
Mobile
misc
- design/mobile-audio Jaana Burcu Dogan. Proposal: Audio for Mobile. November 30, 2015.
- design/localization Marcel van Lohuizen. Proposal: Localization support in Go. Jan 28, 2016.
- design/unbounded-queue Christian Petrin. Proposal: Built in support for high performance unbounded queue. October 2, 2018
- design/lockfile Adrien Delorme. Proposal: make the internal lockedfile package public. 2019-10-15.
- design/cidr Rudi Kramer, James Forrest. Proposal: Add support for CIDR notation in no_proxy variable. 2017-07-10
- issue/16704 net/http: considering supporting CIDR notation in no_proxy env variable
- design/dns Sam Whited. Proposal: DNS Based Vanity Imports. 2018-06-30.
- issue/26160 proposal: use DNS TXT records for vanity import paths
Unclassified But Relevant Links
Fun Facts
- cl/1 Brian Kernighan. Go’s first commit. Jul 19, 1972.
- issue/9 I have already used the name for MY programming language. Nov 11, 2009
- issue/2870 9 is prime if it’s a hot day. Feb 3, 2012
- doc/gophercount How Many Go Developers Are There?. November 1, 2019.
- discuss/google-owns-go Russ Cox’s response on «Go is Google’s language, not ours»
Acknowledgements
The document author would like to first thank the TalkGo community creator Mai Yang’s champion sponsorship for the golang.design initiative. His creation of the TalkGo significantly changed the Go community in China. He is also a great person that is actively contributing to all kinds of Go related projects.
It is also important to thank the continuing, inspiring discussion and sharing with the TalkGo community core members qcrao, and eddycjy.
The document would not be organized without all of the supports from them.
License
golang.design/history | CC-BY-NC-ND 4.0 © changkun
GO design, производственная компания на карте Перми ул. Халтурина, 8а
Почтовый индекс 614017
Пермь,улица Халтурина, 8а
8 (902) 835-01-07,
8 (902) 800-15-35
8 (342) 265-80-20
Как доехать на общественном транспорте:
- Мебель на заказ;
- Мебель для кухни;
- Корпусная мебель
«GO design» на карте Перми
Последний отзыв:
Об этой компании еще нет ни одного отзыва
GoDesign
Ниже представлена наша доступная очередь проектов. Если вы хотите сотрудничать с нами или у вас есть вопросы о доступных типах участия, пожалуйста, свяжитесь с нами здесь
Центральное ограждение Hope
Стоимость 12000 долларов США
Поскольку детей принимают в Центр надежды, потребуется соответствующее ограждение, чтобы обеспечить безопасную среду для этих детей. Ограждение будет блочное.
Сбор дождевой воды Hope Center
Стоимость 15000 долларов США
Из-за нехватки воды в этом регионе крыши Центра Надежды могут помочь собрать этот драгоценный ресурс.Финансирование этого проекта позволило бы нам установить водосточную систему в каждом здании и направить воду в несколько цистерн, которые будут собирать и удерживать воду.
Исследовательский центр архитектуры коренных народов GoDesign
До 200 000 долларов США
Исследовательский центр будет изучать архитектурные традиции коренных народов Африканского Рога и использовать собранные данные, чтобы предложить устойчивые решения многих проблем, с которыми сталкиваются эти сообщества.
Обеспечить чистой водой поселок с населением 8000 человек
300 000 долл. США
GoDesign профинансировал обследование водоснабжения в деревне, где мы работаем последние 8 лет.Вода всегда была серьезной проблемой для этих людей. Обследование показало, что в пределах 2 км от города имеется водозабор, который обеспечит достаточное количество воды для всего сообщества. Основная проблема заключается в том, что вода находится на глубине 300 метров под землей.
Строительство школы в Аваше
50 000–300 000 долл. США
GoDesign столкнулся с огромной потребностью в строительстве школ для детей как в детских садах, так и в старших классах. В общей сложности потребуется 6 зданий, чтобы обеспечить этим детям безопасную среду для обучения и развития.Каждое здание будет стоить примерно 50 000 долларов.
GoDesign Maker Space
20 000 долл. США
Эта инициатива направлена на обслуживание малообеспеченных слоев населения путем обучения и обучения их использованию местных материалов и методов для создания продуктов, отвечающих потребностям быстро развивающейся строительной индустрии Эфиопии.
Контакты — Go Design Go
Мы любим демонстрировать контент приглашенных авторов; Мы рады, что вы здесь!
Веб-сайт GoDesignGo получает в среднем 15 000 посетителей от дизайнеров до энтузиастов дизайна и продается во всех 4 центрах дизайна Cohen: D&D Building NYC, Pacific Design Center LA, DCOTA Miami и декоративном центре Хьюстоне. .
Если у вас есть исключительные навыки письма, вы знакомы с сообществом дизайнеров интерьеров и хотели бы поделиться своим опытом и идеями, мы будем рады услышать от вас!
Основы для каждого поста, который мы публикуем
Успешный вклад гостей — это всеобъемлющие, основанные на данных и интересные посты, которые учат наших читателей чему-то новому о мире дизайна интерьера.
Мы также ищем кое-что во всем, что публикуем:
- Оригинальные концепции, убедительные аргументы и высококачественное письмо.Мы не будем переиздавать то, что было опубликовано где-либо еще.
- Статья отражает стиль / тон письма GoDesignGo. Мы стремимся быть непринужденными, но элегантными и с чувством стиля!
- Надлежащая атрибуция данных, цитат и стороннего контента, на который есть ссылки в статье.
- Не более одной ссылки на веб-сайт вашей компании (Примечание. Это включает в себя домашнюю страницу вашего веб-сайта, блог, страницу с ценами и т. Д.) В теле сообщения.
Что мы не приемлем
- Все, что уже освещалось в нашем блоге ранее.Пожалуйста, сделайте поиск на нашем сайте, прежде чем отправлять свои статьи.
- Все, что может быть истолковано как схема построения ссылок.
- Все, что слишком рекламирует вашу компанию или организацию.
- Все, что является оскорбительным или неточным.
- Все, что чрезмерно критично по отношению к отдельным лицам или компаниям — это не сайт для подачи жалоб.
Не очень мелкий шрифт
Для публикации материалы должны соответствовать стандартам качества редакции GoDesignGo.Редакторы оставляют за собой право отклонить материалы по своему усмотрению.
Если вы заинтересованы в участии в блоге GoDesignGo, пожалуйста, придерживайтесь рекомендаций и отправьте свое предложение с помощью формы ниже:
GO Designs Inc. — Эль-Пасо, Техас, США 79903
Джордж Окампо начал в индустрии бассейнов в качестве дизайнера и работал на одного из крупнейших 40-летних строителей в США. За время своего пребывания там он выиграл большинство национальных наград за дизайн для этой компании.Он быстро понял, что хочет большего, чем просто создание продукта. Джордж хотел использовать свой дизайн, работу и опыт, удостоенные национальных наград, чтобы создать лучший продукт с лучшим обслуживанием. Джордж не просто разрабатывает идею, он отрабатывает чувства своего клиента и его потребностей, а затем тратит большую часть своего времени на подготовку проекта. Джордж устанавливает планку: профилирование, дренаж и усиление фундамента, чтобы продукт, реконструкция или внешний вид дома через годы после его завершения выглядели как новые.GO Designs стремится создать качественное пространство с хорошей энергией, балансом, потоком, качественными материалами и прочной основой. Джордж превратит любое видение в реальность и сделает процесс максимально плавным, чтобы создать истинный смысл «дома».
Предоставленные услуги
Проектирование и строительство беседок, Установка искусственной травы, Кирпичная кладка, Конструкция из бетона, Окрашивание бетона, Изготовленные на заказ площадки для игры в мяч для игры в бочче, Изготовленные по индивидуальному заказу пожарные ямы, Индивидуальное укладывание зелени, Индивидуальные водные элементы, Снос, Строительство собачьей беговой дорожки, Установка капельного орошения , Засухоустойчивый ландшафтный дизайн, Установка заборов, Дизайн сада, Установка ворот, Проектирование и строительство беседок, Обустройство территории, Батуты в земле, Ремонт ирригации, Установка ирригационных систем, Ландшафтное строительство, Установка ландшафтной дренажной системы, Установка ландшафтного освещения, Уход за ландшафтом, Аэрация газонов , Уход за газонами, Стрижка газонов, Посев газонов, Обработка газонов и удобрение, Каменная кладка, Мульчирование, Органические сады, Строительство наружных каминов, Строительство наружных кухонь, Установка наружного освещения, Строительство патио, Установка асфальтоукладчиков, Строительство беседок, Озеленение, Озеленение бассейна, Подпорная стена Строительство, Установка дерна, Дождеватель S Установка системы, Строительство бассейна, Посадка деревьев, Строительство решеток, Установка деревянных заборов, Строительство и реконструкция каменной кладки, Строительство решеток и беседок
Обслуживаемых территорий
Канутильо, Эль-Пасо, Форт-Блисс, Форт-Блисс, Сокорро, Нью-Мексико, Западный Техас
Награды
Best of Houzz 2014,15,16,17,18,19 & 20.Эль-ПасоИнк, Лучшее в Эль-Пасо 2020. Награда Гильдии Мастеров Бассейнов, получившая награду Дизайнер-16 / Победитель премии NSPI, Дизайнер-7 Роскошные бассейны, Реестр элитных строителей бассейнов / City Magazine-El Paso / SuCasa-El Paso
SOLID Go Design — Вершина глупости
Этот пост основан на тексте моего выступления на GolangUK 18 августа 2016 года.
Запись выступления доступна на YouTube.
Этот пост был переведен на упрощенный китайский пользователем Haohao Tian .Спасибо, Haohao!
Это сообщение перевел на русский язык Артем Зиновьев. Спасибо, Артем!
Сколько в мире программистов на Go? Придумайте число и держите его в голове, мы вернемся к нему в конце этого выступления.
Кто здесь выполняет проверку кода в рамках своей работы? [вся комната подняла руки, что обнадеживает]. Хорошо, а почему вы делаете ревью кода? [кто-то крикнул: «Чтобы остановить плохой код»]
Если проверка кода предназначена для выявления плохого кода, то как узнать, является ли проверяемый код хорошим или плохим?
Теперь можно сказать «этот код некрасивый» или «вау, исходный код прекрасен», точно так же, как вы могли бы сказать «эта картина прекрасна» или «эта комната прекрасна», но это субъективные термины, и я ищу объективные способы говорить о свойствах хорошего или плохого кода.
Какие свойства плохого кода вы можете уловить при проверке кода?
- Жесткий . Код жесткий? Есть ли у него смирительная рубашка властных типов и параметров, затрудняющих модификацию?
- Хрупкий . Код хрупкий? Не вызывает ли малейшее изменение базы кода неописуемый хаос?
- Неподвижный . Сложно ли рефакторинг кода? Это одно нажатие клавиши до цикла импорта?
- Комплекс .Есть ли код ради кода?
- Подробно . Использовать код просто утомительно? Когда вы смотрите на него, можете ли вы даже сказать, что этот код пытается сделать?
Это позитивно звучащие слова? Вы были бы рады видеть эти слова в обзоре вашего кода?
Наверное, нет.
Но это улучшение, теперь мы можем сказать что-то вроде «Мне это не нравится, потому что это слишком сложно изменить» или «Мне это не нравится, потому что я не могу сказать, что пытается сделать код», но как насчет того, чтобы вести с позитивом?
Разве не было бы замечательно, если бы существовали способы описать свойства хорошего дизайна, а не только плохого, и уметь делать это объективно?
В 2002 году Роберт Мартин опубликовал свою книгу Agile Software Development, Principles, Patterns, and Practices .В нем он описал пять принципов проектирования программного обеспечения многократного использования, которые он назвал принципами SOLID после первых букв в их названиях.
- Принцип единой ответственности
- Принцип открытия / закрытия
- Лисков Принцип замещения
- Принцип разделения интерфейса
- Принцип инверсии зависимостей
Эта книга немного устарела, языки, о которых она говорит, использовались более десяти лет назад. Но, возможно, есть некоторые аспекты принципов SOLID, которые могут дать нам ключ к пониманию того, как говорить о хорошо разработанных программах Go.
Итак, это то, о чем я хочу поговорить с вами сегодня утром.
Первый принцип SOLID, буква S, — принцип единственной ответственности.
У класса должна быть одна и только одна причина для изменения.
–Роберт Мартин
Now Go, очевидно, не имеет классов — вместо этого у нас есть гораздо более мощное понятие композиции — но если вы можете не обращать внимания на использование слова «класс», я думаю, что здесь есть некоторая ценность.
Почему важно, чтобы у фрагмента кода была только одна причина для изменения? Что ж, сколь бы печальной ни была мысль о том, что ваш собственный код может измениться, гораздо более неприятно обнаружить, что код, от которого зависит ваш код, меняется у вас под ногами.И когда ваш код действительно должен измениться, он должен быть изменен в ответ на прямые стимулы, он не должен быть жертвой побочного ущерба.
Таким образом, код, который несет единственную ответственность, имеет наименьшее количество причин для изменения.
Сцепление и сцепление
Два слова, описывающие, насколько легко или сложно изменить часть программного обеспечения, — это связь и согласованность.
Связь — это просто слово, которое описывает две вещи, изменяющиеся вместе: движение в одном вызывает движение в другом.
Родственное, но отдельное понятие — это идея сплоченности, силы взаимного притяжения.
В контексте программного обеспечения связность — это свойство описания частей кода, которые естественно притягиваются друг к другу.
Чтобы описать элементы сцепления и согласованности в программе Go, мы могли бы поговорить о функциях и методах, что очень часто встречается при обсуждении SRP, но я считаю, что это начинается с модели пакета Go.
Имена пакетов
В Go весь код находится внутри пакета, и хорошо разработанный пакет начинается с его имени.Имя пакета является одновременно описанием его назначения и префиксом пространства имен. Вот несколько примеров хороших пакетов из стандартной библиотеки Go:
-
net / http
, который предоставляет http-клиенты и серверы. -
os / exec
, который запускает внешние команды. -
encoding / json
, который реализует кодирование и декодирование документов JSON.
Когда вы используете символы другого пакета внутри своего собственного, это достигается с помощью объявления `import`, которое устанавливает связь на уровне исходного кода между двумя пакетами.Теперь они знают друг о друге.
Неверные имена пакетов
Такая ориентация на имена — не просто педантизм. Пакет с плохо названным именем упускает возможность перечислить его назначение, если оно вообще когда-либо было.
Что предоставляет сервер распространения пакетов
? … Ну сервер, надеюсь, но какой протокол?
Что предоставляет частный пакет
? Вещи, которые я не должен видеть? Должны ли быть какие-то публичные символы?
И общий пакет
, как и его соучастник в преступлении, package utils
, часто находится рядом с другими преступниками.
Catch — все подобные пакеты становятся свалкой для разных вещей, и, поскольку у них много обязанностей, они меняются часто и без причины.
Философия UNIX Go
На мой взгляд, ни одно обсуждение разделенного проектирования не будет полным без упоминания философии Unix Дуга Макилроя; маленькие, острые инструменты, которые объединяются для решения более крупных задач, часто задач, которые не были предусмотрены первоначальными авторами.
Я думаю, что пакеты Go воплощают дух философии UNIX.По сути, каждый пакет Go сам по себе представляет собой небольшую программу Go, единый блок изменений, несущий единственную ответственность.
Второй принцип, буква O, является принципом открытости и закрытости Бертрана Мейера, который в 1988 году написал:
Программные объекты должны быть открыты для расширения, но закрыты для модификации.
— Бертран Мейер, Построение объектно-ориентированного программного обеспечения
Как этот совет применим к языку, написанному 21 год спустя?
основной пакет type A struct { год int } func (a A) Greet () {fmt.Println ("Hello GolangUK", год назад)} type B struct { А } func (b B) Greet () {fmt.Println ("Добро пожаловать в GolangUK", b.year)} func main () { var a A год = 2016 var b B b.year = 2016 a.Greet () // Привет, GolangUK, 2016 b.Greet () // Добро пожаловать на GolangUK 2016 }
У нас есть тип A
, с полем год
и метод Greet
. У нас есть второй тип, B
, который встраивает и A
, таким образом, вызывающие абоненты видят методы B
, наложенные на A
, потому что A
встроен как поле в B
, и B
может предоставлять свой собственный метод Greet
, скрывая метод A
.
Но встраивание предназначено не только для методов, оно также обеспечивает доступ к полям встроенного типа. Как видите, поскольку A
и B
определены в одном пакете, B
может получить доступ к частному полю года
A
, как если бы оно было объявлено внутри B
.
Таким образом, встраивание — это мощный инструмент, позволяющий открывать типы Go для расширения.
основной пакет type Cat struct { Строка имени } func (c Cat) Legs () int {return 4} func (c Cat) PrintLegs () { fmt.Printf ("У меня% d ног \ n", c.Legs ()) } type OctoCat struct { Кот } func (o OctoCat) Legs () int {return 5} func main () { var octo OctoCat fmt.Println (octo.Legs ()) // 5 octo.PrintLegs () // У меня 4 ноги }
В этом примере у нас есть тип Cat
, который может подсчитать количество ног с помощью метода Legs
. Мы встраиваем этот тип Cat
в новый тип OctoCat
и объявляем, что у Octocat
пять ножек.Однако, хотя OctoCat
определяет свой собственный метод Legs
, который возвращает 5, при вызове метода PrintLegs
он возвращает 4.
Это связано с тем, что PrintLegs
определен для типа Cat
. Он принимает Cat
в качестве получателя и поэтому отправляет по методу Cat
Legs
. Cat
не знает типа, в который он был встроен, поэтому его набор методов не может быть изменен путем встраивания.
Таким образом, мы можем сказать, что типы Go, будучи открытыми для расширения , являются закрытыми для модификации .
По правде говоря, методы в Go — это не более чем синтаксический сахар вокруг функции с заранее объявленным формальным параметром, их получателем.
func (c Cat) PrintLegs () { fmt.Printf ("У меня% d ног \ n", c.Legs ()) } func PrintLegs (c Cat) { fmt.Printf ("У меня% d ног \ n", c.Legs ()) }
Приемник — это именно то, что вы передаете в него, первый параметр функции, и поскольку Go не поддерживает перегрузку функций, OctoCat
s не могут быть заменены на обычные Cat
s.Это подводит меня к следующему принципу.
Введенный Барбарой Лисков, принцип подстановки Лискова, грубо говоря, гласит, что два типа могут быть заменены, если они демонстрируют такое поведение, что вызывающий не может различить разницу.
В языке, основанном на классах, принцип подстановки Лискова обычно интерпретируется как спецификация абстрактного базового класса с различными конкретными подтипами. Но в Go нет классов или наследования, поэтому подстановка не может быть реализована в терминах абстрактной иерархии классов.
Интерфейсы
Напротив, замещение является прерогативой интерфейсов Go. В Go от типов не требуется указывать, что они реализуют конкретный интерфейс, вместо этого любой тип реализует интерфейс, просто при условии, что у него есть методы, подпись которых соответствует объявлению интерфейса.
Мы говорим, что в Go интерфейсы удовлетворяются неявно, а не явно, и это оказывает глубокое влияние на то, как они используются в языке.
Хорошо спроектированные интерфейсы, скорее всего, будут небольшими; Превалирует идиома: интерфейс содержит только один метод.Из этого логически следует, что небольшие интерфейсы приводят к простым реализациям, потому что иначе сделать трудно. Это приводит к пакетам, состоящим из простых реализаций, связанных общим поведением .
io.Reader
Интерфейс считывателя типа{ // Чтение читает до len (buf) байтов в buf. Чтение (buf [] байт) (n int, ошибка ошибки) }
Это подводит меня к io.Reader
, моему любимому интерфейсу Go.
Файл io.Интерфейс читалки очень простой; Чтение
считывает данные в предоставленный буфер и возвращает вызывающей стороне количество прочитанных байтов и любую ошибку, обнаруженную во время чтения. Это кажется простым, но очень мощным.
Поскольку io.Reader
имеет дело со всем, что может быть выражено как поток байтов, мы можем построить считыватели практически для чего угодно; постоянная строка, байтовый массив, стандартный вход, сетевой поток, tar-файл gzip’d, стандартная команда, выполняемая удаленно через ssh.
И все эти реализации взаимозаменяемы, потому что они выполняют один и тот же простой контракт.
Итак, принцип замещения Лискова, примененный к го, можно резюмировать этим прекрасным афоризмом покойного Джима Вейриха.
Не требуй больше, не обещай меньше.
— Джим Вейрих
И это отличный переход к четвертому принципу SOLID.
Четвертый принцип — это принцип разделения интерфейса, который гласит:
Клиенты не должны зависеть от методов, которые они не используют.
–Роберт К. Мартин
В Go применение принципа сегрегации интерфейса может относиться к процессу изоляции поведения, необходимого для того, чтобы функция выполняла свою работу. В качестве конкретного примера, скажем, мне дали задание написать функцию, которая сохраняет на диске структуру Document
.
// Сохранить записывает содержимое документа в файл f. func Save (f * os.File, doc * Document) ошибка
Я мог бы определить эту функцию, назовем ее Сохранить
, что требует * os.Файл
в качестве места назначения для записи прилагаемого документа
. Но здесь есть несколько проблем.
Подпись Сохранить
исключает возможность записи данных в сетевое расположение. Если предположить, что сетевое хранилище может потребоваться позже, подпись этой функции должна измениться, что повлияет на всех ее вызывающих.
Поскольку Save
работает напрямую с файлами на диске, тестировать его неприятно. Чтобы проверить его работу, тест должен будет прочитать содержимое файла после записи.Кроме того, тест должен гарантировать, что f
был записан во временное хранилище и всегда впоследствии удалялся.
* os.File
также определяет множество методов, которые не имеют отношения к Save
, например чтение каталогов и проверка, является ли путь символической ссылкой. Было бы полезно, если бы подпись нашей функции Save
могла описывать только релевантные части * os.File
.
Что мы можем сделать с этими проблемами?
// Save записывает содержимое документа в предоставленный ReadWriterCloser.func Save (rwc io.ReadWriteCloser, doc * Document) ошибка
Используя io.ReadWriteCloser
, мы можем применить принцип разделения интерфейса, чтобы переопределить Save
, чтобы получить интерфейс, который описывает более общие вещи в виде файлов.
С этим изменением любой тип, реализующий интерфейс io.ReadWriteCloser
, может быть заменен на предыдущий * os.File
. Это делает Save
более широким в своем применении и разъясняет вызывающему Save
, какие методы * os.Тип файла
имеет отношение к его работе.
Как автор Save
, у меня больше нет возможности вызывать эти несвязанные методы в * os.File
, поскольку он скрыт за интерфейсом io.ReadWriteCloser
. Но мы можем пойти немного дальше в отношении принципа разделения интерфейсов.
Во-первых, маловероятно, что если Save
следует принципу единой ответственности, он прочитает только что записанный файл, чтобы проверить его содержимое — за это должен отвечать другой фрагмент кода.Таким образом, мы можем сузить спецификацию для интерфейса, который мы передаем, до . Сохраните
, чтобы просто написать и закрыть.
// Save записывает содержимое документа в предоставленный WriteCloser. func Save (wc io.WriteCloser, doc * Document) ошибка
Во-вторых, предоставление Save
механизма закрытия его потока, который мы унаследовали, чтобы сделать его похожим на объект в форме файла, поднимает вопрос о том, при каких обстоятельствах wc
будет закрыт. Возможно, Save
вызовет Close
безоговорочно, или, возможно, Close
будет вызван в случае успеха.
Это представляет проблему для вызывающего Сохранить
, поскольку он может захотеть записать дополнительные данные в поток после того, как документ будет записан.
type NopCloser struct { io.Writer } // Закрытие не влияет на базовый писатель. func (c * NopCloser) Close () error {return nil}
Грубым решением было бы определить новый тип, который включает io.Writer
и переопределяет метод Close
, предотвращая закрытие базового потока Save
.
Но это, вероятно, было бы нарушением принципа замены Лискова, поскольку NopCloser
на самом деле ничего не закрывает.
// Save записывает содержимое документа в предоставленный Writer. func Save (w io.Writer, doc * Document) ошибка
Лучшим решением было бы переопределить Save
, чтобы он принимал только io.Writer
, полностью сняв с него ответственность делать что-либо, кроме записи данных в поток.
Применяя принцип разделения интерфейса к нашей функции Save
, результаты одновременно были функцией, которая является наиболее конкретной с точки зрения ее требований — ей требуется только то, что доступно для записи — и самой общей по своей функции, мы теперь можно использовать Save
, чтобы сохранить наши данные во что-нибудь, что реализует io.Писатель
.
Отличное практическое правило для Go — принимать интерфейсы, возвращать структуры .
— Джек Линдамуд
Если отступить на несколько шагов назад, то эта цитата представляет собой интересный мем, который просачивается в духе времени Го в течение последних нескольких лет.
В этой версии размером с твит отсутствуют нюансы, и это не вина Джека, но я думаю, что она представляет собой один из первых элементов защищенных знаний о дизайне Го.
Последний принцип SOLID — это принцип инверсии зависимостей, который гласит:
Модули высокого уровня не должны зависеть от модулей низкого уровня.Оба должны зависеть от абстракций.
Абстракции не должны зависеть от деталей. Детали должны зависеть от абстракций.
–Роберт К. Мартин
Но что на практике означает инверсия зависимостей для программистов Go?
Если вы применили все принципы, о которых мы говорили до этого момента, то ваш код уже должен быть разбит на отдельные пакеты, каждый из которых имеет одну четко определенную ответственность или цель. Ваш код должен описывать свои зависимости в терминах интерфейсов, и эти интерфейсы должны быть факторизованы, чтобы описывать только поведение, которое требуется этим функциям.Другими словами, делать нечего.
Итак, я думаю, что Мартин говорит здесь, разумеется, в контексте Go, — это структура вашего графа импорта.
В Go график импорта должен быть ациклическим. Несоблюдение этого ациклического требования является основанием для сбоя компиляции, но, что более важно, представляет собой серьезную ошибку в дизайне.
При прочих равных, граф импорта хорошо разработанной программы Go должен быть широким и относительно плоским, а не высоким и узким.Если у вас есть пакет, функции которого не могут работать, не прибегая к помощи другого пакета, это, возможно, признак того, что код недостаточно хорошо разложен по границам пакета.
Принцип инверсии зависимостей побуждает вас переложить ответственность за особенности, как можно выше по графику импорта, на основной пакет
или обработчик верхнего уровня, оставляя код нижнего уровня заниматься абстракциями-интерфейсами.
Напомним, что применительно к Go каждый из принципов SOLID является мощным утверждением о дизайне, но вместе взятые они имеют центральную тему.
Принцип единой ответственности побуждает вас структурировать функции, типы и методы в пакеты, которые демонстрируют естественную сплоченность; типы принадлежат друг другу, функции служат одной цели.
Принцип открытости / закрытости побуждает вас объединять простые типы в более сложные с помощью встраивания.
Принцип замены Лискова побуждает вас выражать зависимости между вашими пакетами в терминах интерфейсов, а не конкретных типов. Определяя небольшие интерфейсы, мы можем быть более уверены в том, что реализации будут точно соответствовать своему контракту.
Принцип замены интерфейса развивает эту идею и побуждает вас определять функции и методы, которые зависят только от того поведения, которое им нужно. Если вашей функции требуется только параметр типа интерфейса с одним методом, то более вероятно, что эта функция несет только одну ответственность.
Принцип инверсии зависимостей поощряет вас переносить знания о вещах, от которых ваш пакет зависит от времени компиляции — в Go мы видим это с уменьшением количества операторов import
, используемых конкретным пакетом, — во время выполнения.
Если резюмировать этот разговор, то, вероятно, так оно и есть; Интерфейсы позволяют применять принципы SOLID к программам Go .
Потому что интерфейсы позволяют программистам Go описывать то, что предоставляет их пакет, а не то, как он это делает. Это просто еще один способ сказать «разъединение», что действительно является целью, потому что программное обеспечение, которое слабо связано, — это программное обеспечение, которое легче изменить.
Как отмечает Санди Мец:
Дизайн — это искусство упорядочивания кода, который должен работать сегодня и легко менять навсегда .
–Sandi Metz
Потому что, если Go станет языком, в который компании инвестируют в долгосрочной перспективе, поддержка программ Go, простота которых они могут изменить, будет ключевым фактором в их решении.
В заключение, давайте вернемся к вопросу, с которого я начал эту беседу; Сколько в мире программистов на Go? Это моя догадка:
К 2020 году будет 500 000 разработчиков Go.
-я
На что полмиллиона программистов на Go потратят свое время? Что ж, очевидно, они напишут много кода Go, и, если честно, не все из них будут хорошими, а некоторые будут довольно плохими.
Пожалуйста, поймите, что я говорю это не из жестокости, но каждый из вас в этой комнате, имеющий опыт разработки на других языках — языках, с которых вы пришли в Go — знает на собственном опыте, что есть элемент правда к этому предсказанию.
В C ++ изо всех сил пытается выйти намного меньший и более чистый язык.
— Бьярн Страуструп, Разработка и развитие C ++
Возможность для всех программистов Go сделать наш язык успешным напрямую зависит от нашей коллективной способности не создавать такой беспорядок, о котором люди начинают говорить о Go так, как они сегодня шутят о C ++.
Повествование, которое высмеивает другие языки за раздутость, многословность и чрезмерную сложность, однажды может быть обращено на Go, и я не хочу, чтобы это произошло, поэтому у меня есть просьба.
ПрограммистамGo нужно меньше говорить о фреймворках и больше говорить о дизайне. Нам нужно перестать сосредотачиваться на производительности любой ценой и вместо этого сосредоточиться на повторном использовании любой ценой.
Я хочу, чтобы люди говорили о том, как использовать язык, который у нас есть сегодня, независимо от его выбора и ограничений, для разработки решений и решения реальных проблем.
Я хочу услышать, как люди говорят о том, как разрабатывать программы Go таким образом, чтобы они были хорошо спроектированы, разделены, допускали повторное использование и, прежде всего, реагировали на изменения.
Замечательно, что так много из вас сегодня собрались здесь, чтобы послушать великолепный состав ораторов, но реальность такова, что независимо от того, насколько крупной станет эта конференция, по сравнению с количеством людей, которые будут использовать Go в течение всего ее существования, мы это всего лишь крошечная доля.
Итак, мы должны рассказать остальному миру, как нужно писать хорошее программное обеспечение.Хорошее программное обеспечение, составное программное обеспечение, программное обеспечение, которое можно изменить, и покажите им, как это сделать с помощью Go. И это начинается с вас.
Я хочу, чтобы вы начали говорить о дизайне, возможно, воспользуетесь некоторыми из идей, которые я представил здесь, надеюсь, вы проведете собственное исследование и примените эти идеи в своих проектах. Тогда я хочу, чтобы вы:
- Напишите об этом в блоге.
- Расскажите об этом на семинаре, что вы делали.
- Напишите книгу о том, что вы узнали.
- И вернитесь на эту конференцию в следующем году и расскажите о том, чего вы достигли.
Потому что, делая эти вещи, мы можем создать культуру разработчиков Go, которые заботятся о программах, которые рассчитаны на длительный срок службы.
Спасибо.
шаблонов проектирования в Go | Udemy
Обзор курса
Этот курс предоставляет всесторонний обзор шаблонов проектирования в Go с практической точки зрения. Этот курс, в частности, охватывает шаблоны с использованием:
Последние версии языка программирования Go
Использование современных библиотек и фреймворков программирования
Использование современных инструментов разработчика, таких как JetBrains GoLand
Обсуждение вариаций паттернов и альтернативных подходов
Этот курс предоставляет обзор всех паттернов проектирования «Банда четырех» (GoF), изложенных в их основополагающей книге, вместе с современными вариациями, корректировками, обсуждениями внутреннего использования паттернов. на языке.
Что такое шаблоны проектирования?
Шаблоны проектирования — это многократно используемые решения общих проблем программирования. Они были популяризированы в 1994 году в книге Design Patterns: Elements of Reusable Object-Oriented Software автора Erich Gamma, John Vlissides, Ralph Johnson и Richard Helm (которые широко известны как «Банда четырех», отсюда и аббревиатура GoF).
В оригинальной книге GoF book в качестве примеров использовались C ++ и Smalltalk, но с тех пор шаблоны проектирования были адаптированы для всех мыслимых языков программирования: C #, Java, Swift, Python, JavaScript, а теперь — Go!
Привлекательность шаблонов проектирования бессмертна: мы видим их в библиотеках, некоторые из них являются неотъемлемой частью языков программирования, и вы, вероятно, используете их ежедневно, даже если не подозреваете, что они там есть.
Какие шаблоны охватывает этот курс?
Этот курс охватывает всех шаблонов проектирования GoF. Фактически, вот полный список того, что рассматривается:
Принципы проектирования SOLID : Принцип единой ответственности, Принцип открытого-закрытого, Принцип подстановки Лискова, Принцип разделения интерфейса и Принцип инверсии зависимостей
Шаблоны творческого проектирования : Builder, Factories (Factory Method и Abstract Factory), Prototype и Singleton
Шаблоны структурного проектирования : адаптер, мост, композит, декоратор, фасад, легковес и прокси
Шаблоны поведенческого проектирования : Цепочка Ответственности, Командование, Интерпретатор, Итератор, Посредник, Мементо, Наблюдатель, Состояние, Стратегия, Шаблонный метод и Посетитель
Для кого предназначен курс?
Этот курс предназначен для разработчиков Go, которые хотят увидеть не только учебные примеры шаблонов проектирования, но также различные вариации и приемы, которые можно применить для реализации шаблонов проектирования современным способом.Например, использование шаблона Composite позволяет выполнять итерацию структур и позволяет скалярным объектам маскироваться, как если бы они были коллекциями.
Стиль презентации
Этот курс представляет собой (очень большую) серию живых демонстраций, проводимых в JetBrains GoLand и представленных с использованием механизма рендеринга Kinetica. Kinetica устраняет визуальный беспорядок в среде IDE, заставляя вас сосредоточиться на коде, который отлично отображается, независимо от того, смотрите ли вы курс на большом экране или на мобильном телефоне.
Большинство демонстраций являются однофайловыми, поэтому вы можете загрузить файл, прикрепленный к уроку, и запустить его в GoLand или другой IDE по вашему выбору (или просто запустить их из командной строки).
В этом курсе не используются диаграммы классов UML; все демонстрации сделаны с помощью живого кодирования.
паттернов дизайна Go | Packt
Когда вы пишете первые строчки какой-нибудь библиотеки, сложно внести много ошибок. Но по мере того, как исходный код становится все больше и больше, становится легче ломать вещи.Команда растет, и теперь многие люди пишут один и тот же исходный код, новые функции добавляются поверх кода, который вы написали в начале. И код перестал работать из-за некоторой модификации какой-то функции, которую теперь никто не может отследить.
Это распространенный сценарий на предприятиях, который тестирование пытается сократить (оно не решает его полностью, это не Святой Грааль). Когда вы пишете модульные тесты в процессе разработки, вы можете проверить, не нарушает ли какая-то новая функция что-то старое или ваша текущая новая функция выполняет все, что ожидается в требованиях.
Go имеет мощный пакет для тестирования, который позволяет легко работать в среде TDD. Также очень удобно проверять части вашего кода без необходимости писать все основное приложение, которое его использует.
Тестирование очень важно для каждого языка программирования. Создатели Go знали об этом и решили предоставить все библиотеки и пакеты, необходимые для тестирования, в основном пакете. Вам не нужны сторонние библиотеки для тестирования или покрытия кода.
Пакет, позволяющий тестировать приложения Go, обычно называется тестированием.Мы создадим небольшое приложение, которое суммирует два числа, которые мы вводим через командную строку:
func main () { // Atoi преобразует строку в int a, _: = strconv.Atoi (os.Args [1]) b, _: = strconv.Atoi (os.Args [2]) результат: = сумма (a, b) fmt.Printf ("Сумма% d и% d равна% d \ n", a, b, результат) } func sum (a, b int) int { вернуть a + b }
Запустим нашу программу в терминале и получим сумму:
$ go run main.перейти 3 4 Сумма 3 и 4 составляет 7
Кстати, мы используем пакет strconv
для преобразования строк в другие типы, в данном случае в int
. Метод Atoi
получает строку и возвращает int
и ошибку
, которые для простоты мы здесь игнорируем (с помощью подчеркивания).
Подсказка
Вы можете игнорировать возвращаемые переменные, используя при необходимости символы подчеркивания, но обычно вы не хотите игнорировать ошибки.
Хорошо, давайте напишем тест, который проверяет правильный результат суммы. Мы создаем новый файл с именем main_test.go
. По соглашению, тестовые файлы именуются как файлы, которые они тестируют, плюс суффикс _test
:
func TestSum (t * testing.T) { а: = 5 б: = 6 ожидается: = 11 res: = сумма (a, b) if res! = expected { t.Errorf ("Наша функция суммы не работает,% d +% d не% d \ n", a, b, res) } }
Testing in Go используется для записи методов, начинающихся с префикса Test
, имени теста и внедрения теста .Указатель Т
называется т
. В отличие от других языков, в Go нет утверждений или специального синтаксиса для тестирования. Вы можете использовать синтаксис Go для проверки ошибок, и вы можете позвонить по номеру t
и сообщить информацию об ошибке в случае сбоя. Если код доходит до конца функции Test
без возникновения ошибок, функция прошла тесты.
Чтобы запустить тест в Go, вы должны использовать ключевое слово команды go test -v
( -v
— получить подробный вывод из теста), как показано ниже:
$ go test -v === ВЫПОЛНИТЬ TestSum --- ПРОЙДЕН: TestSum (0.00с) ПРОХОД хорошо github.com/go-design-patterns/introduction/ex_xx_testing 0,001 с
Наши тесты прошли правильно. Посмотрим, что произойдет, если мы намеренно что-нибудь сломаем и изменим ожидаемое значение теста с 11
на 10
:
$ go test --- ОТКАЗ: TestSum (0,00 с) main_test.go: 12: Наша функция суммы не работает, 5 + 6 не 10 ОТКАЗ статус выхода 1 FAIL github.com / sayden / go-design-patterns / введение / ex_xx_testing 0.002s
Тест не прошел (как мы и ожидали). Пакет тестирования предоставляет информацию, которую вы задали для теста. Давайте снова заставим его работать и проверим тестовое покрытие. Измените значение переменной ожидаемый
с 10
на 11
снова и запустите команду go test -cover
, чтобы увидеть покрытие кода:
$ go test -cover ПРОХОД Охват : 20,0% заявлений ок, github.com / sayden / go-design-patterns / введение / ex_xx_testing 0.001s
Параметры -cover
предоставляют нам информацию о покрытии кода для данного пакета. К сожалению, он не предоставляет информации об общем покрытии приложений.
TDD — это аббревиатура от Test Driven Development . Он состоит из написания тестов перед написанием функции (вместо того, что мы делали раньше, когда мы сначала писали функцию sum
, а затем мы писали функцию test
).
TDD изменяет способ написания кода и структурный код, чтобы его можно было протестировать (много кода, который вы можете найти в GitHub, даже код, который вы, вероятно, написали в прошлом, вероятно, очень сложно, если не невозможно, протестировать ).
Итак, как это работает? Поясним это на примере из жизни — представьте, что вы летом и хотите как-то освежиться. Вы можете построить бассейн, наполнить его холодной водой и прыгнуть в него. Но в терминах TDD шаги будут такими:
Вы переходите в место, где будет построен пул (вы пишете тест, который, как вы знаете, не удастся).
Больно … да и ты не крут (да … тест провалился, как мы и предсказывали).
Вы строите бассейн и наполняете его холодной водой (вы кодируете функциональность).
Вы прыгаете в бассейн (вы снова повторяете тест по пункту 1).
Тебе сейчас холодно. Потрясающий! Объект сдан (тест пройден).
Подойдите к холодильнику и возьмите пива в бассейн. Напиток. Двойная крутизна (рефакторинг кода).
Итак, давайте повторим предыдущий пример, но с умножением. Сначала мы напишем объявление функции, которую собираемся протестировать:
func multiply (a, b int) int { возврат 0 }
Теперь напишем тест, который проверит правильность предыдущей функции:
import "testing" func TestMultiply (t * testing.T) { а: = 5 б: = 6 ожидается: = 30 res: = умножить (a, b) if res! = expected { т.Errorf ("Наша функция умножения не работает,% d *% d не% d \ n", a, b, res) } }
И тестируем через командную строку:
$ go test --- ОТКАЗ: TestMultiply (0,00 с) main_test.go: 12: Наша функция умножения не работает, 5 + 6 - нет 0 ОТКАЗ статус выхода 1 FAIL github.com/sayden/go-designpatterns/introduction/ex_xx_testing/multiply 0,002 с
Ницца.Как и в нашем примере с бассейном, где воды еще не было, наша функция также возвращает неверное значение. Итак, теперь у нас есть объявление функции (но еще не определено) и неудачный тест. Теперь мы должны пройти тест, написав функцию и выполнив тест для проверки:
func multiply (a, b int) int { возврат а * б }
И мы снова выполняем наш набор тестов. После правильного написания кода тест должен пройти, чтобы мы могли продолжить процесс рефрактора:
$ go test ПРОХОД ок, github.com / sayden / go-design-patterns / введение / ex_xx_testing / multiply 0,001 с
Отлично! Мы разработали функцию умножить
после TDD. Теперь мы должны провести рефакторинг нашего кода, но мы не можем сделать его более простым или читаемым, чтобы цикл можно было считать закрытым.
В этой книге мы напишем множество тестов, которые определят функциональность, которую мы хотим достичь в наших шаблонах. TDD способствует инкапсуляции и абстракции (как и шаблоны проектирования).
Часто задаваемые вопросы (FAQ) — язык программирования Go
Истоки
Какова цель проекта?
Во время создания Go, всего десять лет назад, мир программирования отличался от сегодняшнего.Производственное программное обеспечение обычно писалось на C ++ или Java, GitHub не существовало, большинство компьютеров еще не были многопроцессорными, и кроме Visual Studio и Eclipse было несколько доступных IDE или других инструментов высокого уровня. вообще, не говоря уже о том, чтобы бесплатно в Интернете.
Между тем мы были разочарованы чрезмерной сложностью, необходимой для использования языки, с которыми мы работали при разработке серверного программного обеспечения. Компьютеры стали намного быстрее с тех пор, как такие языки, как C, C ++ и Java были впервые разработаны, но процесс программирования еще не сам продвинулся почти на столько же.Также было ясно, что мультипроцессоры становятся универсальными, но большинство языков мало помогли в их эффективном программировании и безопасно.
Мы решили сделать шаг назад и подумать, в чем заключались основные проблемы. в ближайшие годы будет доминировать в разработке программного обеспечения, поскольку технологии разработаны, и как новый язык может помочь в их решении. Например, появление многоядерных процессоров доказывало, что язык должен обеспечить первоклассную поддержку некоторого вида параллелизма или параллелизма.А чтобы сделать управление ресурсами управляемым в большой параллельной программе, Требовалась сборка мусора или, по крайней мере, какое-то безопасное автоматическое управление памятью.
Эти соображения привели к а серия дискуссий, из которых возникло Го, сначала как набор идей и desiderata, тогда как язык. Общей целью было сделать так, чтобы Go больше помогал работающему программисту. путем включения инструментов, автоматизации рутинных задач, таких как форматирование кода, и устранение препятствий для работы с большими кодовыми базами.
Гораздо более подробное описание целей Go и того, как их встречают, или хотя бы приближают, есть в статье, Зайдите в Google: Языковой дизайн на службе разработки программного обеспечения.
Какова история проекта?
Роберт Гриземер, Роб Пайк и Кен Томпсон начали рисовать цели по новому языку на доске 21 сентября 2007 г. В течение нескольких дней цели превратились в план действий. и четкое представление о том, что это будет.Дизайн продолжался неполный рабочий день в параллельно с несвязанной работой. К январю 2008 года Кен приступил к работе. на компиляторе, с помощью которого можно исследовать идеи; он сгенерировал код C как его выход. К середине года язык стал полноценным проектом и достаточно успокоился, чтобы попытаться создать производственный компилятор. В мае 2008 г. Ян Тейлор независимо начал работу над интерфейсом GCC для Go, используя проект спецификации. Расс Кокс присоединился к команде в конце 2008 года и помог перевести язык и библиотеки от прототипа к реальности.
Go стал общедоступным проектом с открытым исходным кодом 10 ноября 2009 года.Бесчисленное количество людей из сообщества поделились идеями, обсуждениями и кодом.
Сейчас миллионы программистов Go — сусликов — по всему миру, и с каждым днем их становится все больше. Успех Go намного превзошел наши ожидания.
Откуда появился талисман суслика?
Талисман и логотип были разработаны Рене Френч, которая также проектировала Гленда, зайчик Plan 9. Сообщение в блоге про суслика объясняет, как это было полученный из одного, который она использовала для WFMU Дизайн футболки несколько лет назад.Логотип и талисман покрыты Лицензия Creative Commons Attribution 3.0 лицензия.
У суслика есть образец листа проиллюстрировать его характеристики и как правильно их представить. Лист модели впервые был показан в разговаривать Рене на Gophercon в 2016 году. У него уникальные особенности; он же Go-gopher , а не какой-нибудь старый суслик.
Этот язык называется го или голанг?
Язык называется Go. Прозвище «голанг» возникло потому, что веб-сайт голанг.орг, а не go.org, который был нам недоступен. Однако многие используют имя голанг, и это удобно, поскольку этикетка. Например, тег Twitter для языка — «#golang». В любом случае, название языка просто Go.
Примечание: хотя официальный логотип имеет две заглавные буквы, название языка пишется Go, а не GO.
Почему вы создали новый язык?
Go родился из-за разочарования существующими языками и среды для работы, которую мы делали в Google.Программирование стало слишком отчасти виноват выбор языков. Нужно было выберите либо эффективную компиляцию, либо эффективное выполнение, либо простоту программирование; все три не были доступны в одном и том же мейнстриме язык. Программисты, которые могли выбрать легкость, а не безопасность и эффективность за счет перехода на языки с динамической типизацией, такие как Python и JavaScript, а не C ++ или, в меньшей степени, Java.
Не только мы беспокоились. После многих лет довольно спокойного пейзажа для языков программирования, Go был одним из первых из нескольких новых языков — Rust, Elixir, Swift и другие, которые сделали разработку языков программирования снова активная, почти мейнстримная сфера.
Go решил эти проблемы, попытавшись объединить простоту программирования интерпретируемого, динамически типизированный язык с эффективностью и безопасностью статически типизированного компилируемого языка. Он также был нацелен на то, чтобы быть современным, с поддержкой сетевых и многоядерных вычисления. Наконец, работа с Go должна быть быстрой : это должно занять максимум несколько секунд для создания большого исполняемого файла на одном компьютере. Для достижения этих целей необходимо решить ряд лингвистические вопросы: выразительная, но легкая система шрифтов; параллелизм и сборка мусора; жесткая спецификация зависимостей; и так далее.Их невозможно решить с помощью библиотек или инструментов; новый язык был востребован.
Статья Перейти в Google обсуждает предысторию и мотивацию разработки языка Go, а также предоставляет более подробную информацию о многих ответах, представленных в этом FAQ.
Какие предки Го?
Go в основном относится к семейству C (базовый синтаксис), со значительным вкладом Паскаль / Модула / Оберон семья (объявления, пакеты), плюс несколько идей из языков вдохновленный CSP Тони Хора, такие как Newsqueak и Limbo (параллелизм).Тем не менее, это новый язык по всем направлениям. Во всех отношениях язык был разработан мышлением о том, чем занимаются программисты и как заниматься программированием, по крайней мере, тип программирования, который мы делаем, более эффективный, а значит, больше удовольствия.
Каковы руководящие принципы в дизайне?
Когда был разработан Go, Java и C ++ были наиболее распространенными использовал языки для написания серверов, по крайней мере, в гугле. Мы чувствовали, что эти языки требуют слишком много бухгалтерии и повторений.Некоторые программисты отреагировали переходом к более динамичным, гибкие языки, такие как Python, за счет эффективности и безопасность типа. Мы чувствовали, что эффективность должна быть возможной, безопасность и плавность на одном языке.
Go пытается уменьшить объем набора текста в обоих смыслах этого слова.
В дизайне мы постарались уменьшить беспорядок и
сложность. Нет предварительных объявлений и файлов заголовков;
все декларируется ровно один раз. Инициализация выразительна,
автоматический и простой в использовании.Синтаксис чистый и легкий по ключевым словам.
Повторение ( foo.Foo * myFoo = new (foo.Foo)
) сокращается на
простой вывод типа с использованием : =
конструкция объявления и инициализации. И, пожалуй, самое радикальное, что там
нет иерархии типов: типы — это , они не должны
объявить о своих отношениях. Эти упрощения позволяют Go быть
выразительный, но понятный без ущерба, ну, изощренности.
Другой важный принцип — поддерживать ортогональность концепций.Методы могут быть реализованы для любого типа; структуры представляют данные, в то время как интерфейсы представляют собой абстракцию; и так далее. Ортогональность делает это легче понять, что происходит, когда вещи сочетаются.
Использование
Google использует Go для внутренних целей?
да. Go широко используется в продакшене внутри Google.
Один простой пример — сервер, стоящий за
golang.org.
Это просто godoc
сервер документов, работающий в производственной конфигурации на
Google App Engine.
Более значительным примером является сервер загрузки Google, dl.google.com
,
который предоставляет двоичные файлы Chrome и другие крупные устанавливаемые файлы, такие как apt-get
пакеты.
Go — далеко не единственный язык, используемый в Google, но это ключевой язык. по ряду направлений, в том числе надежность сайта инженерия (SRE) и крупномасштабная обработка данных.
Какие еще компании используют Go?
Использование Go растет во всем мире, особенно, но ни в коем случае не исключительно. в области облачных вычислений. Несколько крупных проектов облачной инфраструктуры, написанных на Go: Докер и Кубернетес, но их гораздо больше.
Но дело не только в облаке. Go Wiki включает страница, регулярно обновляется, в нем перечислены некоторые из многих компаний, использующих Go.
В Wiki также есть страница со ссылками на Истории успеха о компаниях и проектах, использующих язык.
Связаны ли программы Go с программами C / C ++?
Можно использовать C и Go вместе в одном адресном пространстве, но это не совсем естественно и может потребоваться специальное интерфейсное программное обеспечение. Кроме того, связывание C с кодом Go освобождает память свойства безопасности и управления стеком, которые предоставляет Go.Иногда для решения проблемы абсолютно необходимо использовать библиотеки C, но при этом всегда возникает элемент риска, которого нет в чистый код Go, так что делайте это осторожно.
Если вам действительно нужно использовать C с Go, дальнейшие действия зависят от Go.
реализация компилятора.
Есть три реализации компилятора Go, поддерживаемые
Вперед, команда.
Это gc
, компилятор по умолчанию, gccgo
, который использует серверную часть GCC,
и несколько менее зрелый gollvm
, использующий инфраструктуру LLVM.
Gc
использует другое соглашение о вызовах и компоновщик из C и
поэтому не может быть вызван непосредственно из программ C, или наоборот.
Программа cgo
обеспечивает механизм для
«Интерфейс внешней функции», чтобы обеспечить безопасный вызов
Библиотеки C из кода Go.
SWIG расширяет эту возможность до библиотек C ++.
Вы также можете использовать cgo
и SWIG с Gccgo
и gollvm
.
Поскольку они используют традиционный API, также возможно, с большой осторожностью,
для связывания кода из этих компиляторов напрямую с программами C или C ++, скомпилированными с помощью GCC / LLVM.Однако для этого необходимо понимать соглашения о вызовах для
все соответствующие языки, а также забота об ограничениях стека при вызове C или C ++
от Go.
Какие IDE поддерживает Go?
Проект Go не включает пользовательскую среду IDE, но язык и библиотеки были разработаны, чтобы упростить анализ исходного кода. Как следствие, большинство известных редакторов и IDE поддерживают Go well, либо напрямую, либо через плагин.
Список известных IDE и редакторов с хорошей поддержкой Go доступно включает Emacs, Vim, VSCode, Atom, Eclipse, Sublime, IntelliJ (через специальный вариант под названием Goland) и многое другое.Скорее всего, ваша любимая среда будет продуктивной для программирование на Go.
Поддерживает ли Go буферы протокола Google?
Отдельный проект с открытым исходным кодом предоставляет необходимый плагин компилятора и библиотеку. Он доступен на github.com/golang/protobuf/.
Могу ли я перевести домашнюю страницу Go на другой язык?
Абсолютно. Мы призываем разработчиков создавать сайты Go Language на своих языках. Однако, если вы решите добавить логотип или бренд Google на свой сайт (не отображается на golang.org), вам нужно будет соблюдать правила, указанные на www.google.com/permissions/guidelines.html
Дизайн
Есть ли в Go среда выполнения?
В Go есть обширная библиотека, называемая средой выполнения ,
это часть каждой программы Go.
Библиотека времени выполнения реализует сборку мусора, параллелизм,
управление стеком и другие важные функции языка Go.
Хотя он более важен для языка, среда выполнения Go аналогична
в libc
, библиотеку C.
Однако важно понимать, что среда выполнения Go не включить виртуальную машину, например, предоставляемую средой выполнения Java. Программы Go заранее компилируются в машинный код (или JavaScript или WebAssembly для некоторых вариантов реализации). Таким образом, хотя этот термин часто используется для описания виртуального среда, в которой выполняется программа, в Go слово «время выполнения» это просто название библиотеки, предоставляющей критически важные языковые услуги.
Что случилось с идентификаторами Unicode?
При разработке Go мы хотели убедиться, что это не чрезмерно ориентированный на ASCII, что означало расширение пространства идентификаторов из пределы 7-битного ASCII.Правило Go — символы идентификатора должны быть буквы или цифры в соответствии с определением Unicode — легко понять и реализовать, но с ограничениями. Комбинированные символы исключено по дизайну, например, и это исключает некоторые языки, такие как деванагари.
У этого правила есть еще одно неприятное последствие.
Поскольку экспортируемый идентификатор должен начинаться с
заглавная буква, идентификаторы, созданные из символов
на некоторых языках по определению нельзя экспортировать.
На данный момент
единственное решение — использовать что-то вроде X 日本語
, что
явно неудовлетворительно.
Начиная с самой ранней версии языка, было значительно подумал, как лучше всего расширить пространство идентификаторов для размещения программисты, использующие другие родные языки. Что именно делать, остается активной темой обсуждения, и в будущем версия языка может быть более либеральной в своем определении идентификатора. Например, он может перенять некоторые идеи из Unicode. рекомендации организации для идентификаторов. Что бы ни случилось, это должно быть совместимо с сохранением (или, возможно, расширение) того, как регистр букв определяет видимость идентификаторы, которые остаются одной из наших любимых функций Go.
На данный момент у нас есть простое правило, которое позже может быть расширено. без нарушения программ, который позволяет избежать ошибок, которые наверняка возникнут из правила, допускающего неоднозначные идентификаторы.
Почему в Go нет функции X?
Каждый язык содержит новые функции и пропускает чью-то любимую особенность. Go был разработан с учетом удачности программирования, скорости компиляция, ортогональность концепций и необходимость поддержки функций такие как параллелизм и сборка мусора.Ваша любимая функция может быть отсутствует, потому что он не подходит, потому что это влияет на скорость компиляции или ясность дизайна, или потому что это сделало бы фундаментальную модель системы слишком трудно.
Если вас беспокоит, что в Go отсутствует функция X , пожалуйста, простите нас и исследуйте возможности Go. Вы можете найти это они интересным образом компенсируют отсутствие X .
Почему в Go нет универсальных типов?
Языковое предложение реализация формы универсальных типов была принята для включение в язык.Если все пойдет хорошо, он будет доступен в версии Go 1.18.
Go был задуман как язык для написания серверных программ, которые легко поддерживать с течением времени. (Видеть это статью для получения дополнительной информации.) Дизайн был сосредоточен на таких вещах, как масштабируемость, удобочитаемость и параллелизм. Полиморфное программирование не казалось важным для языка целей в то время, поэтому для простоты он был опущен.
Язык стал более зрелым, и есть возможность рассмотреть некоторая форма общего программирования.Однако остаются некоторые оговорки.
Дженерики удобны, но они обходятся дорого. сложность в системе типов и времени выполнения. Мы еще не нашли дизайн, который дает ценность, пропорциональную сложности, хотя мы продолжать думать об этом. Между тем, встроенные карты и фрагменты Go, плюс возможность использовать пустой интерфейс для создания контейнеров (с явной распаковкой) означает, что во многих случаях можно написать код, который делает то, что позволяют дженерики, хотя и менее плавно.
Тема остается открытой. Посмотрите на несколько предыдущих неудачных попыток разработать хорошее универсальное решение для Go, см. это предложение.
Почему в Go нет исключений?
Мы считаем, что привязка исключений к элементу управления
структура, как в идиоме try-catch-finally
, приводит к
запутанный код. Это также побуждает программистов маркировать
слишком много обычных ошибок, таких как невозможность открытия файла, как
исключительный.
Go использует другой подход.Для простой обработки ошибок многозначный return позволяет легко сообщить об ошибке, не перегружая возвращаемое значение. Канонический тип ошибки, связанный с другими функциями Go делает обработку ошибок приятной, но совсем другой от этого на других языках.
Го тоже есть парочка встроенных функций для сигнализации и восстановления после действительно исключительных условия. Механизм восстановления выполняется только в составе состояние функции срывается после ошибки, чего достаточно чтобы справиться с катастрофой, но не требует дополнительных структур управления и, при правильном использовании может привести к созданию чистого кода обработки ошибок.
Подробнее см. В статье «Отложить, паника и восстановление». Кроме того, сообщения в блоге о значениях ошибок описывает один подход к чистой обработке ошибок в Go, демонстрируя, что поскольку ошибки — это просто значения, вся мощь Go может быть использована в обработке ошибок.
Почему в Go нет утверждений?
Go не предоставляет утверждений. Они бесспорно удобны, но наши опыт показывает, что программисты используют их как костыль, чтобы не думать о правильной обработке ошибок и составлении отчетов.Правильная обработка ошибок означает, что серверы продолжают работать вместо сбоя после нефатальной ошибки. Правильный отчет об ошибках означает, что ошибки являются прямыми и точными, избавление программиста от интерпретации большой трассировки сбоя. Точный ошибки особенно важны, когда программист, видя ошибки не знаком с кодом.
Мы понимаем, что это предмет разногласий. В язык Go и библиотеки, которые отличаются от современных практик, просто потому что мы чувствуем, что иногда стоит попробовать другой подход.
Зачем строить параллелизм на идеях CSP?
Параллелизм и многопоточное программирование со временем заработал репутацию трудного человека. Мы считаем, что отчасти это связано со сложными такие конструкции, как pthreads и отчасти из-за чрезмерного внимания к деталям низкого уровня такие как мьютексы, условные переменные и барьеры памяти. Интерфейсы более высокого уровня позволяют упростить код, даже если мьютексы и тому подобное под одеялом.
Одна из самых успешных моделей лингвистической поддержки высокого уровня поскольку параллелизм исходит от коммуникационных последовательных процессов Хоара, или CSP.Оккам и Эрланг — два хорошо известных языка, которые происходят от CSP. Примитивы параллелизма в Go происходят из другой части генеалогического древа. чей главный вклад — мощное представление о каналах как о первоклассных объектах. Опыт работы с несколькими более ранними языками показал, что модель CSP хорошо вписывается в рамки процедурного языка.
Почему горутины вместо потоков?
Горутины упрощают использование параллелизма. Идея, у которой есть существует какое-то время, заключается в том, чтобы мультиплексировать независимо выполняя функции — сопрограммы — на набор потоков.Когда сопрограмма блокируется, например, вызывая системный вызов блокировки, среда выполнения автоматически перемещает другие сопрограммы на той же операционной системный поток в другой работающий поток, чтобы они не были заблокированы. Программист ничего этого не видит, и в этом суть. Результат, который мы называем горутинами, может быть очень дешевым: у них мало накладные расходы сверх памяти для стека, составляющие всего несколько килобайт.
Чтобы сделать стеки небольшими, во время выполнения Go используются ограниченные стеки изменяемого размера.Недавно На отчеканенную горутину отводится несколько килобайт, которых почти всегда достаточно. Когда это не так, во время выполнения увеличивается (и уменьшается) объем памяти для хранения стек автоматически, позволяя многим горутинам жить в скромных объем памяти. Накладные расходы ЦП в среднем составляют около трех дешевых инструкций на вызов функции. Практично создавать сотни тысяч горутин в одном и том же адресное пространство. Если бы горутины были просто потоками, системные ресурсы были бы выбегают в гораздо меньшем количестве.
Почему операции карты не определены как атомарные?
После долгого обсуждения было решено, что для типичного использования карт не требуется безопасный доступ из нескольких горутин, и в тех случаях, когда это было, карта была вероятно, часть какой-то более крупной структуры данных или вычислений, которые уже были синхронизировано.Поэтому требование, чтобы все операции с картой захватывали мьютекс, замедлили бы вниз большинство программ и добавление безопасности немногим. Это было нелегкое решение, однако, поскольку это означает, что неконтролируемый доступ к карте может привести к сбою программы.
Язык не препятствует обновлению атомарной карты. При необходимости такие как и при размещении ненадежной программы, реализация может заблокировать доступ к карте.
Доступ к карте небезопасен только при обновлении.
Пока все горутины только читают — ищут элементы на карте,
включая итерацию с использованием для
range
loop — без изменения карты
путем присвоения элементам или выполнения удалений,
для них безопасен одновременный доступ к карте без синхронизации.
В помощь правильному использованию карты некоторые реализации языка содержат специальную проверку, которая автоматически сообщает во время выполнения, когда карта изменяется небезопасно при одновременном исполнении.
Вы примете мою смену языка?
Люди часто предлагают улучшить язык — список рассылки содержит богатую историю таких обсуждений, но очень немногие из этих изменений был принят.
Хотя Go — проект с открытым исходным кодом, язык и библиотеки защищены. обещанием совместимости, которое предотвращает изменения, которые нарушают работу существующих программ, по крайней мере, на уровне исходного кода (программы, возможно, потребуется время от времени перекомпилировать, чтобы оставаться в актуальном состоянии).Если ваше предложение нарушает спецификацию Go 1, мы даже не сможем принять участие идея, независимо от ее достоинств. Будущий основной выпуск Go может быть несовместим с Go 1, но обсуждения работа над этой темой только началась, и одно можно сказать наверняка: таких несовместимостей будет очень мало. Более того, обещание совместимости побуждает нас указывать автоматический путь ждем, чтобы старые программы адаптировались в случае возникновения такой ситуации.
Даже если ваше предложение совместимо со спецификацией Go 1, оно может не соответствовать целям дизайна Go.Артикул Go в Google: Языковой дизайн на службе разработки программного обеспечения объясняет происхождение Go и мотивацию его дизайна.
Типы
Go — объектно-ориентированный язык?
Да и нет. Хотя Go имеет типы и методы и позволяет объектно-ориентированный стиль программирования, нет иерархии типов. Концепция «интерфейса» в Go предлагает другой подход, мы считаем, что он прост в использовании и в некотором смысле более общий. Есть также способы встраивания типов в другие типы, чтобы предоставить что-то аналогично — но не идентично — подклассу.Более того, методы в Go более общие, чем в C ++ или Java: они могут быть определены для любого типа данных, даже для встроенных типов, таких как как простые, «распакованные» целые числа. Они не ограничиваются структурами (классами).
Кроме того, отсутствие иерархии типов заставляет «объекты» в Go чувствовать себя гораздо более легче, чем в таких языках, как C ++ или Java.
Как получить динамическую отправку методов?
Единственный способ иметь динамически отправляемые методы — использовать интерфейс. Методы структуры или любого другого конкретного типа всегда разрешаются статически.
Почему нет наследования типов?
Объектно-ориентированное программирование, по крайней мере, на самых известных языках, слишком много обсуждает отношения между типами, отношения, которые часто могут быть получены автоматически. Go берет другой подход.
Вместо того, чтобы требовать от программиста заранее объявить, что два типы связаны, в Go тип автоматически удовлетворяет любому интерфейсу который определяет подмножество его методов. Помимо сокращения бухгалтерский учет, такой подход имеет реальные преимущества.Типы могут удовлетворить сразу несколько интерфейсов, без сложностей традиционных множественное наследование. Интерфейсы могут быть очень легкими — интерфейс с один или даже ноль методов могут выразить полезную концепцию. Интерфейсы могут быть добавлены постфактум, если возникнет новая идея или для тестирования — без аннотации исходных типов. Потому что нет явных отношений между типами и интерфейсы, нет иерархии типов, чтобы управлять или обсуждать.
Эти идеи можно использовать для построения чего-то аналогичного
типобезопасные каналы Unix.Например, посмотрите, как fmt.Fprintf
позволяет отформатировать печать на любом выходе, а не только в файл, или как bufio
пакет может быть полностью отделен от файлового ввода-вывода,
или как пакеты image
генерируют сжатые
файлы изображений. Все эти идеи проистекают из единого интерфейса.
( io.Writer
), представляющий единственный метод
( Напишите
). И это только малая часть.
Интерфейсы Go имеют огромное влияние на структуру программ.
К этому нужно привыкнуть, но этот неявный стиль типа зависимость — одна из самых продуктивных вещей в Go.
Почему
len
— это функция, а не метод? Мы обсуждали этот вопрос, но решили
реализация len
и его друзей в качестве функций была прекрасна на практике и
не усложнял вопросы по интерфейсу (в смысле типа Go)
основных типов.
Почему Go не поддерживает перегрузку методов и операторов?
Отправка методов упрощается, если также не требуется выполнять сопоставление типов.Опыт работы с другими языками показал нам, что наличие множества методы с одинаковыми именами, но разными сигнатурами иногда были полезны но на практике это может сбивать с толку и быть хрупким. Соответствие только по имени и требование согласованности типов было важным упрощающим решением в системе типов Go.
Что касается перегрузки оператора, это кажется скорее удобством, чем абсолютным требование. Опять же, без него все проще.
Почему в Go нет деклараций «реализует»?
Тип Go удовлетворяет интерфейс, реализуя методы этого интерфейса, ничего больше.Это свойство позволяет определять и использовать интерфейсы без необходимо изменить существующий код. Это позволяет структурная типизация, которая способствует разделению проблем и улучшает повторное использование кода, а также упрощает использовать шаблоны, которые появляются по мере развития кода. Семантика интерфейсов — одна из основных причин шустрости Go, легкость на ощупь.
Подробнее см. В вопросе о наследовании типов.
Как я могу гарантировать, что мой тип соответствует интерфейсу?
Вы можете попросить компилятор проверить, что тип T
реализует
интерфейс I
путем попытки присвоения с использованием нулевого значения для T
или указатель на T
, в зависимости от случая:
тип T struct {} var _ I = T {} // Проверяем, что T реализует I.var _ I = (* T) (nil) // Убедитесь, что * T реализует I.
Если T
(или * T
соответственно) не реализует I
, ошибка будет обнаружена во время компиляции.
Если вы хотите, чтобы пользователи интерфейса явно заявляли, что они реализуют вы можете добавить метод с описательным именем к набору методов интерфейса. Например:
type Fooer interface { Фу () РеализуетFooer () }
Затем тип должен реализовать метод ImplementsFooer
, чтобы быть Fooer
, четко документируя факт и сообщая об этом в
перейти к выводу документа.
type Bar struct {} func (b Bar) ImplementsFooer () {} func (b Bar) Foo () {}
В большинстве кодов такие ограничения не используются, поскольку они ограничивают полезность идея интерфейса. Однако иногда они необходимы для устранения неясностей. среди аналогичных интерфейсов.
Почему тип T не удовлетворяет интерфейсу Equal?
Рассмотрим этот простой интерфейс для представления объекта, который может сравнивать сам с другим значением:
type Equaler interface { Равный (Equaler) bool }
и этот тип, T
:
тип T int func (t T) Equal (u T) bool {return t == u} // не удовлетворяет Equaler
В отличие от аналогичной ситуации в некоторых системах полиморфного типа, T
не реализует Equaler
.Тип аргумента T. Equal
— T
,
не буквально требуемый тип Equaler
.
В Go система типов не поддерживает аргумент Equal
; это ответственность программиста, так как
проиллюстрирован типом T2
, который реализует Equaler
:
тип T2 int func (t T2) Equal (u Equaler) bool {return t == u. (T2)} // удовлетворяет Equaler
Но даже это не похоже на другие системы типов, потому что в Go любой тип, который удовлетворяет Equaler
, может быть передан как
аргумент к Т2.Равно
, и во время выполнения мы должны
убедитесь, что аргумент имеет тип T2
.
Некоторые языки обеспечивают эту гарантию во время компиляции.
Связанный пример идет другим путем:
type Opener interface { Открыть () Читатель } func (t T3) Открыть () * os.File
В Go, T3
не удовлетворяет Opener
,
хотя может и на другом языке.
Хотя это правда, что система типов Go делает меньше для программиста. в таких случаях отсутствие подтипов делает правила о Удовлетворенность интерфейсом очень легко определить: являются ли имена функций а подписи именно те из интерфейса? Правило Go также легко реализовать эффективно.Мы считаем, что эти преимущества компенсируют отсутствие автоматическое продвижение типа. Должен пойти однажды принять какую-нибудь форму полиморфного печатая, мы ожидаем, что найдется способ выразить идею этих примеры, а также их статическая проверка.
Могу ли я преобразовать [] T в [] интерфейс {}?
Не прямо.
Это запрещено спецификацией языка, потому что два типа
не имеют такого же представления в памяти.
Необходимо копировать элементы по отдельности в место назначения
кусочек.В этом примере фрагмент int
преобразуется в фрагмент интерфейс {}
:
t: = [] int {1, 2, 3, 4} s: = make ([] интерфейс {}, len (t)) для i, v: = диапазон t { s [i] = v }
Могу ли я преобразовать [] T1 в [] T2, если T1 и T2 имеют один и тот же базовый тип?
Эта последняя строка этого примера кода не компилируется.тип T1 int тип T2 int var t1 T1 var x = T2 (t1) // ОК var st1 [] T1 var sx = ([] T2) (st1) // НЕ ОК
В Go типы тесно связаны с методами, так как каждый именованный тип имеет (возможно, пустой) набор методов.Общее правило состоит в том, что вы можете изменить имя типа преобразован (и, следовательно, возможно, изменит свой набор методов), но вы не можете изменить имя (и набор методов) элементов составного типа. Go требует, чтобы вы четко указывали на преобразование типов.
Почему значение моей ошибки nil не равно нулю?
Под крышками интерфейсы выполнены в виде двух элементов, тип T
и значение В
. V
— конкретное значение, например int
, struct
или указатель, но не сам интерфейс, и имеет
тип Т
.Например, если мы сохраним int
значение 3 в интерфейсе,
результирующее значение интерфейса схематично
( T = int
, V = 3
).
Значение V
также известно как интерфейсное динамическое значение ,
поскольку данная переменная интерфейса может содержать разные значения V
(и соответствующие типы T
)
во время выполнения программы.
Значение интерфейса — ноль
, только если V
и T
оба не установлены ( T = nil
, V
не установлено),
В частности, интерфейс nil
всегда будет содержать тип nil
.Если мы сохраним nil
указатель типа * int
внутри
значение интерфейса, внутренний тип будет * int
независимо от значения указателя:
( T = * int
, V = ноль
).
Таким образом, такое значение интерфейса будет отличным от nil
, даже если значение указателя V
внутри равно nil
.
Эта ситуация может сбивать с толку и возникает, когда значение nil
равно
хранится внутри значения интерфейса, такого как ошибка , возврат
:
func returnsError () error { var p * MyError = nil if bad () { p = ErrBad } return p // Всегда будет возвращать ошибку, отличную от нуля.}
Если все идет хорошо, функция возвращает nil
p
,
поэтому возвращаемое значение — это ошибка интерфейс
удержание значения ( T = * MyError
, V = nil
).
Это означает, что если вызывающий объект сравнивает возвращенную ошибку с nil
,
это всегда будет выглядеть так, как будто произошла ошибка, даже если ничего плохого не произошло.
Чтобы вернуть вызывающему абоненту правильную ошибку nil
,
функция должна возвращать явный nil
:
func returnsError () error { if bad () { вернуть ErrBad } вернуть ноль }
Это хорошая идея для функций
которые возвращают ошибки, всегда использовать тип ошибки
в
их подпись (как мы сделали выше), а не конкретный тип, такой
как * MyError
, чтобы гарантировать, что ошибка
создан правильно.В качестве примера, os. Открыть
возвращает ошибку
, хотя, если не nil
,
это всегда конкретного типа * os.PathError
.
Ситуации, аналогичные описанным здесь, могут возникнуть всякий раз, когда используются интерфейсы.
Просто имейте в виду, что если какое-либо конкретное значение
был сохранен в интерфейсе, интерфейс не будет nil
.
Для получения дополнительной информации см.
Законы отражения.
Почему нет немаркированных союзов, как в C?
Нетегированные союзы нарушат безопасность памяти Go гарантии.
Почему в Go нет вариантных типов?
Типы вариантов, также известные как алгебраические типы, позволяют указать что значение может принимать один из набора других типов, но только те типы. Обычный пример в системном программировании указывает, что ошибка — это, скажем, сетевая ошибка, ошибка безопасности или приложение ошибка и позволяет вызывающему абоненту определить источник проблемы проверив тип ошибки. Другой пример — синтаксическое дерево в котором каждый узел может быть разного типа: декларация, инструкция, присвоение и так далее.
Мы рассматривали возможность добавления типов вариантов в Go, но после обсуждения решил не учитывать их, потому что они сбивают с толку с интерфейсами. Что будет, если элементы вариантного типа сами были интерфейсы?
Кроме того, некоторые варианты адресов уже охвачены язык. Пример ошибки легко выразить с помощью интерфейса. значение для хранения ошибки и переключатель типа для различения случаев. В Пример синтаксического дерева также возможен, хотя и не так элегантно.
Почему в Go нет ковариантных типов результатов?
Ковариантные типы результатов означают, что интерфейс, подобный
type Copyable interface { Copy () интерфейс {} }
был бы удовлетворен методом
func (v Значение) Копировать () Значение
, потому что Значение
реализует пустой интерфейс.
Типы методов в Go должны точно совпадать, поэтому значение Value
не совпадает.
реализовать Копируемый
.
Go разделяет понятие о том, что
Тип делает — свои методы — из реализации типа.Если два метода возвращают разные типы, они не делают одно и то же.
Программисты, которым нужны ковариантные типы результатов, часто пытаются
выражать иерархию типов через интерфейсы.
В Go более естественно иметь четкое разделение между интерфейсами
и реализация.
Значения
Почему в Go не предусмотрены неявные числовые преобразования?
Удобство автоматического преобразования между числовыми типами в C составляет перевешивается путаницей, которую это вызывает. Когда выражение беззнаковое? Насколько велика стоимость? Это переполняется? Является ли результат портативным, независимым машины, на которой он выполняется? Это также усложняет компилятор; «Обычные арифметические преобразования» непросто реализовать и несовместимы между архитектурами.Из соображений переносимости мы решили сделать вещи понятными и понятными. за счет некоторых явных преобразований в коде. Определение констант в Go — значения произвольной точности бесплатно подписи и аннотаций размера — значительно улучшает ситуацию, хоть.
Связанная деталь заключается в том, что, в отличие от C, int
и int64
являются разными типами, даже если int
— 64-битный тип. int
тип универсальный; если вас волнует, сколько бит хранится в целом числе, Go
призывает вас быть откровенным.
Как константы работают в Go?
Хотя Go строго относится к преобразованию между переменными разных
числовые типы, константы в языке гораздо более гибкие.
Литеральные константы, такие как 23
, 3,14159
и math.Pi
занимают своего рода идеальное числовое пространство с произвольной точностью и
нет переполнения или потери значимости.
Например, значение math.Pi
указано в 63 разрядах.
в исходном коде, а постоянные выражения, включающие значение, сохраняют
точность выше той, которую может удержать float64
.Только когда постоянное или постоянное выражение присваивается
переменная — ячейка памяти в программе — делает
он стал «компьютерным» номером с
обычные свойства с плавающей запятой и точность.
Также, поскольку это просто числа, а не типизированные значения, константы в Go могут быть используется более свободно, чем переменные, тем самым смягчая некоторую неловкость вокруг строгих правил преобразования. Можно написать такие выражения, как
sqrt2: = math.Sqrt (2)
без нареканий со стороны компилятора потому что идеальное число 2
можно безопасно и точно переоборудовать
на float64
для вызова math.Sqrt
.
Сообщение в блоге под названием «Константы» исследует эту тему более подробно.
Почему карты встроены?
По той же причине, что и строки: они такие мощные и важные данные структура, обеспечивающая одну отличную реализацию с синтаксической поддержкой делает программирование более приятным. Мы считаем, что реализация карт в Go достаточно прочен, чтобы служить в подавляющем большинстве случаев. Если конкретное приложение может получить выгоду от индивидуальной реализации, это возможно написать один, но синтаксически это будет не так удобно; это кажется разумным компромиссом.
Почему карты не позволяют использовать срезы в качестве ключей?
Для поиска по карте требуется оператор равенства, который срезы не реализуют. Они не реализуют равенство, потому что для таких типов равенство не определено должным образом; есть несколько соображений, связанных с мелким и глубоким сравнением, указателем и сравнение значений, как работать с рекурсивными типами и т. д. Мы можем вернуться к этому вопросу и реализовать равенство для срезов не сделает недействительными ни одну из существующих программ, но без четкого представления о том, что равенство срезов должно означать, что его пока проще было не учитывать.
В Go 1, в отличие от предыдущих выпусков, равенство определено для структур и массивов, поэтому такие типы могут использоваться как ключи карты. Однако для срезов все еще нет определения равенства.
Почему карты, срезы и каналы являются ссылками, а массивы — значениями?
По этой теме много историй. На раннем этапе карты и каналы были синтаксически указателями, и было невозможно объявить или использовать экземпляр без указателя. Кроме того, мы боролись с тем, как должны работать массивы.В конце концов мы решили, что строгое разделение указателей и ценности усложнили использование языка. Изменение этих типы, которые действуют как ссылки на связанные, разрешенные общие структуры данных эти вопросы. Это изменение добавило некоторой досадной сложности язык, но оказал большое влияние на удобство использования: Go стал более продуктивный, удобный язык, когда он был введен.
Написание кода
Как документируются библиотеки?
Существует программа godoc
, написанная на Go, которая извлекает
пакетная документация из исходного кода и обслуживает ее как веб-сайт
страница со ссылками на объявления, файлы и т. д.Экземпляр работает на
golang.org/pkg/.
Фактически, godoc
реализует полную версию сайта на
golang.org/.
Экземпляр godoc
может быть настроен для предоставления расширенных,
интерактивный статический анализ символов в отображаемых программах; подробности
перечислены здесь.
Для доступа к документации из командной строки инструмент Go имеет док подкоманда, которая предоставляет текстовый интерфейс к той же информации.
Есть ли руководство по стилю программирования на Go?
Нет четкого руководства по стилю, хотя, безусловно, есть узнаваемый «стиль го».
Go установил правила принятия решений
именование, макет и организация файлов.
Документ Effective Go
содержит несколько советов по этим темам.
Если говорить более конкретно, программа gofmt
— прекрасный принтер.
чья цель — обеспечить соблюдение правил макета; он заменяет обычный
сборник правил, которые можно и что нельзя делать, с возможностью интерпретации.
Весь код Go в репозитории и подавляющее большинство в
мир с открытым исходным кодом, был запущен через gofmt
.
Документ под названием Комментарии к обзору кода Go представляет собой сборник очень коротких эссе о деталях идиомы го, которые часто упустили программисты.Это удобный справочник для людей, выполняющих обзоры кода для проектов Go.
Как отправлять патчи в библиотеки Go?
Исходные тексты библиотеки находятся в каталоге репозитория src
.
Если вы хотите внести существенные изменения, пожалуйста, обсудите это в списке рассылки перед тем, как начать.
См. Документ Участие в проекте Go для получения дополнительной информации о том, как действовать.
Почему «go get» использует HTTPS при клонировании репозитория?
Компании часто разрешают исходящий трафик только на стандартные порты TCP 80 (HTTP).
и 443 (HTTPS), блокируя исходящий трафик на других портах, включая TCP-порт 9418
(git) и TCP-порт 22 (SSH).При использовании HTTPS вместо HTTP git
принудительно проверяет сертификат с помощью
default, обеспечивая защиту от атак типа «злоумышленник посередине», подслушивания и взлома.
Поэтому команда go get
использует HTTPS для безопасности.
Git
можно настроить для аутентификации по HTTPS или для использования SSH вместо HTTPS.
Для аутентификации по HTTPS вы можете добавить строку
в файл $ HOME / .netrc
, который git обращается:
машина github.com логин ИМЯ ПОЛЬЗОВАТЕЛЯ пароль APIKEY
Для учетных записей GitHub паролем может быть токен личного доступа.
Git
также можно настроить для использования SSH вместо HTTPS для URL-адресов, соответствующих заданному префиксу.
Например, чтобы использовать SSH для всего доступа к GitHub,
добавьте эти строки в свой ~ / .gitconfig
:
[url "ssh: //[email protected]/"] вместо этогоOf = https://github.com/
Как мне управлять версиями пакетов с помощью «go get»?
В цепочку инструментов Go есть встроенная система для управления наборами связанных пакетов с поддержкой версий, известными как модули .Модули были представлены в Go 1.11 и готовы к использованию в производственной среде с 1.14.
Чтобы создать проект с использованием модулей, запустите go mod init
.
Эта команда создает файл go.mod
, который отслеживает версии зависимостей.
перейти мод init example.com/project
Чтобы добавить, обновить или понизить версию зависимости, запустите и получите
:
иди и получи golang.org/x/[email protected]
См. Учебное пособие: Создание модуля для получения дополнительной информации о том, как начать работу.
Руководства по управлению зависимостями с модулями см. В разделе «Разработка модулей».
Пакеты в модулях должны поддерживать обратную совместимость по мере развития в соответствии с правилом совместимости импорта:
Если старый и новый пакет имеют один и тот же путь импорта,
новый пакет должен быть обратно совместим со старым пакетом.
Рекомендации по совместимости с Go 1 могут служить здесь хорошей справкой: не удаляйте экспортированные имена, поощряйте составные литералы с тегами и т. д.Если требуются другие функции, добавьте новое имя вместо изменения старого.
Модули кодифицируют это с помощью семантического управления версиями и управления версиями семантического импорта.
Если требуется нарушение совместимости, выпустите модуль с новой основной версией.
Для модулей основной версии 2 и выше требуется суффикс основной версии как часть пути (например, / v2
).
Это сохраняет правило совместимости импорта: пакеты в разных основных версиях модуля имеют разные пути.
Указатели и размещение
Когда параметры функции передаются по значению?
Как и во всех языках семейства C, в Go все передается по значению.То есть функция всегда получает копию
передается, как если бы был оператор присваивания, присваивающий
значение параметра. Например, передача значения int
в функцию делает копию int
и передает указатель
value копирует указатель, но не данные, на которые он указывает.
(См. Позже
раздел для обсуждения того, как это влияет на приемники методов.)
Значения карты и среза ведут себя как указатели: они являются дескрипторами, которые содержат указатели на базовую карту или данные среза.Копирование карты или значение среза не копирует данные, на которые оно указывает. Копирование значения интерфейса делает копию вещи, хранящейся в значении интерфейса. Если интерфейс value содержит структуру, копирование значения интерфейса делает копию структура. Если значение интерфейса содержит указатель, копирование значения интерфейса делает копию указателя, но опять же не данных, на которые он указывает.
Обратите внимание, что это обсуждение касается семантики операций. Фактические реализации могут применять оптимизацию, чтобы избежать копирования пока оптимизации не изменяют семантику.
Когда мне следует использовать указатель на интерфейс?
Больше никогда. Указатели на значения интерфейса возникают только в редких, сложных ситуациях, связанных с маскировка типа значения интерфейса для отложенной оценки.
Передача указателя на значение интерфейса — распространенная ошибка. функции, ожидающей интерфейса. Компилятор будет жаловаться на это ошибка, но ситуация все еще может сбивать с толку, потому что иногда указатель необходимо для удовлетворения интерфейса. Понимание состоит в том, что хотя указатель на конкретный тип может удовлетворять интерфейс, за одним исключением указатель на интерфейс никогда не может удовлетворить интерфейс .
Рассмотрим объявление переменной,
var w io.Writer
Функция печати fmt.Fprintf
принимает в качестве первого аргумента
значение, которое удовлетворяет io.Writer
— то, что реализует
канонический метод Написать
. Таким образом, мы можем написать
fmt.Fprintf (w, "привет, мир \ n")
Однако, если мы передадим адрес w
, программа не скомпилируется.
fmt.Fprintf (& w, "hello, world \ n") // Ошибка времени компиляции.
Единственное исключение — любое значение, даже указатель на интерфейс, может быть присвоено
переменная пустого типа интерфейса ( interface {}
).
Даже в этом случае почти наверняка будет ошибкой, если значение будет указателем на интерфейс;
результат может сбивать с толку.
Должен ли я определять методы для значений или указателей?
func (s * MyStruct) pointerMethod () {} // метод указателя func (s MyStruct) valueMethod () {} // метод по значению
Для программистов, не привыкших к указателям, различие между ними
два примера могут сбивать с толку, но на самом деле ситуация очень проста.При определении метода для типа получатель ( s
в приведенном выше
examples) ведет себя точно так же, как если бы он был аргументом метода.
Определять получатель как значение или как указатель — одно и то же
тогда возникает вопрос, должен ли аргумент функции быть значением или
указатель.
Есть несколько соображений.
Во-первых, и это наиболее важно, нужно ли методу изменять
приемник?
Если это так, получатель должен быть указателем.
(Фрагменты и карты действуют как ссылки, поэтому их история немного
более тонкий, но, например, чтобы изменить длину среза
в методе получатель по-прежнему должен быть указателем.)
В приведенных выше примерах, если pointerMethod
изменяет
поля с
,
вызывающий абонент увидит эти изменения, но valueMethod
вызывается с копией аргумента вызывающего (это определение
передачи значения), поэтому вносимые им изменения будут невидимы для вызывающего.
Кстати, в Java-методах получатели всегда являются указателями, хотя их указательная природа несколько замаскирована (и есть предложение добавить в язык получателей ценности). Необычными являются приемники стоимости в Go.
Во-вторых, это соображение эффективности. Если ресивер большой,
например, большой struct
, будет намного дешевле
использовать приемник указателя.
Далее следует последовательность. Если некоторые методы типа должны иметь приемники указателя, остальные тоже должны, поэтому набор методов согласован независимо от того, как используется тип. См. Раздел о наборах методов для подробностей.
Для таких типов, как основные типы, фрагменты и маленькие структуры
,
приемник значения очень дешев, поэтому, если семантика метода
требуется указатель, приемник значения эффективен и понятен.
В чем разница между новым и сделанным?
Вкратце: new
выделяет память, а make
инициализирует
типы фрагментов, карт и каналов.
См. Соответствующий раздел of Effective Go для получения более подробной информации.
Каков размер
int
на 64-битной машине? Размеры int
и uint
зависят от реализации.
но так же, как друг друга на данной платформе.
Для переносимости код, основанный на конкретном
Размер значения должен использовать тип с явно заданным размером, например int64
.На 32-битных машинах компиляторы по умолчанию используют 32-битные целые числа,
в то время как на 64-битных машинах целые числа имеют 64 бита.
(Исторически так было не всегда.)
С другой стороны, скаляры с плавающей запятой и комплексные
типы всегда имеют размер (нет базовых типов float
или complex
),
потому что программисты должны знать о точности при использовании чисел с плавающей запятой.
Тип по умолчанию, используемый для (нетипизированной) константы с плавающей запятой — float64
.
Таким образом, foo
: =
3.0
объявляет переменную foo
типа float64
.
Для переменной float32
, инициализированной (нетипизированной) константой, тип переменной
должно быть явно указано в объявлении переменной:
var foo float32 = 3.0
В качестве альтернативы константе необходимо присвоить тип с преобразованием, как в foo: = float32 (3.0)
.
Как узнать, размещена ли переменная в куче или стеке?
С точки зрения правильности вам не нужно знать.Каждая переменная в Go существует до тех пор, пока на нее есть ссылки. Место хранения, выбранное реализацией, не имеет отношения к семантика языка.
Место хранения действительно влияет на написание эффективных программ. Когда возможно, компиляторы Go будут выделять переменные, которые local для функции в кадре стека этой функции. Однако если компилятор не может доказать, что на переменную нет ссылки после функция возвращает, тогда компилятор должен выделить переменную в Куча со сборкой мусора, чтобы избежать ошибок висячих указателей.Кроме того, если локальная переменная очень большая, это может иметь больше смысла. чтобы хранить его в куче, а не в стеке.
В текущих компиляторах, если у переменной есть адрес, эта переменная является кандидатом на размещение в куче. Тем не менее, основной побег Анализ распознает некоторые случаи, когда такие переменные не живут после возврата из функции и могут находиться в стеке.
Почему мой процесс Go использует так много виртуальной памяти?
Распределитель памяти Go резервирует большую область виртуальной памяти как арену для отчислений.Эта виртуальная память является локальной для конкретного процесса Go; в резервирование не лишает памяти другие процессы.
Чтобы узнать объем фактической памяти, выделенной процессу Go, используйте Unix top
и обратитесь к RES
(Linux) или RSIZE
(macOS) столбцы.
Параллелизм
Какие операции атомарны? А как насчет мьютексов?
Описание атомарности операций в Go можно найти в документ Go Memory Model.
Низкоуровневая синхронизация и атомарные примитивы доступны в синхронизировать и синхронизация / атомарный пакеты. Эти пакеты подходят для простых задач, таких как увеличение подсчет ссылок или гарантия мелкомасштабного взаимного исключения.
Для операций более высокого уровня, таких как координация между одновременных серверов, методы более высокого уровня могут привести к более красивым программам, и Go поддерживает этот подход через его горутины и каналы. Например, вы можете структурировать свою программу так, чтобы только один goroutine по отдельности всегда отвечает за определенный фрагмент данных.Этот подход резюмируется в оригинальном Иди пословица,
Не общайтесь, разделяя память. Вместо этого поделитесь воспоминаниями, общаясь.
См. Раздел «Совместное использование памяти путем передачи кода» и это связанная статья для подробного обсуждения этой концепции.
Большие параллельные программы, вероятно, будут заимствованы из обоих этих наборов инструментов.
Почему моя программа не работает быстрее с большим количеством процессоров?
Будет ли программа работать быстрее с большим количеством процессоров, зависит от проблемы это решение.Язык Go предоставляет примитивы параллелизма, такие как горутины. и каналы, но параллелизм позволяет только параллелизм когда основная проблема по сути параллельна. Проблемы, которые по своей сути являются последовательными, нельзя ускорить, добавив больше процессоров, в то время как те, которые можно разбить на части, которые могут параллельное выполнение может быть ускорено, иногда значительно.
Иногда добавление дополнительных процессоров может замедлить работу программы. На практике программы, которые проводят больше времени синхронизация или общение, чем выполнение полезных вычислений может наблюдаться снижение производительности при использовании несколько потоков ОС.Это связано с тем, что передача данных между потоками включает переключение контекстах, что требует значительных затрат, и эта стоимость может увеличиваться с большим количеством процессоров. Например, пример простого сита из спецификации Go не имеет значительного параллелизма, хотя запускает много горутины; увеличение количества потоков (процессоров) с большей вероятностью замедлит его, чем чтобы ускорить это.
Подробнее по этой теме см. Доклад под названием Параллелизм это не параллелизм.
Как я могу контролировать количество процессоров?
Количество процессоров, доступных одновременно для выполнения горутин, равно
управляется переменной среды оболочки GOMAXPROCS
,
значение по умолчанию — количество доступных ядер ЦП.Поэтому программы с возможностью параллельного выполнения должны
достичь этого по умолчанию на многопроцессорной машине.
Чтобы изменить количество используемых параллельных процессоров,
установите переменную среды или используйте одноименный
функция
пакета времени выполнения, чтобы настроить
поддержка во время выполнения для использования разного количества потоков.
Установка в 1 исключает возможность истинного параллелизма,
принудительное выполнение независимых горутин по очереди.
Среда выполнения может выделить больше потоков, чем значение
из GOMAXPROCS
для обслуживания нескольких невыполненных
Запросы ввода-вывода. GOMAXPROCS
влияет только на количество горутин.
фактически может выполняться сразу; произвольно больше может быть заблокировано
в системных вызовах.
Планировщик горутин в Go не так хорош, как должен быть, хотя он
со временем улучшилось.
В будущем он может лучше оптимизировать использование потоков ОС.
А пока, если есть проблемы с производительностью,
Установка GOMAXPROCS
для каждого приложения может помочь.
Почему нет идентификатора горутины?
У горутин нет имен; они просто анонимные работники.Они не предоставляют программисту ни уникального идентификатора, ни имени, ни структуры данных.
Некоторые люди удивляются этому, ожидая, что идут
.
оператор для возврата некоторого элемента, который можно использовать для доступа и управления
горутина позже.
Основная причина анонимности горутин заключается в том, что полный язык Go доступен при программировании параллельного кода. Напротив, шаблоны использования, которые развиваются, когда потоки и горутины named может ограничивать возможности библиотеки, использующей их.
Вот иллюстрация трудностей.
После того, как кто-то назвал горутину и построил модель вокруг
он становится особенным, и возникает соблазн связать все вычисления
с этой горутиной, игнорируя возможность
использования нескольких, возможно, общих горутин для обработки.
Если пакет net / http
связан по запросу
состояние с горутиной,
клиенты не смогут использовать больше горутин
при обслуживании запроса.
Более того, опыт работы с библиотеками, например, для графических систем. которые требуют, чтобы вся обработка происходила в «основном потоке» показал, насколько неудобным и ограничивающим может быть подход, когда развернут на параллельном языке.Само наличие особой нити или горутины сил программист, чтобы передернуть программу, чтобы избежать сбоев и другие проблемы, вызванные непреднамеренным включением в неправильном потоке.
Для тех случаев, когда конкретная горутина действительно особенная, язык предоставляет такие функции, как каналы, которые можно используются гибкими способами для взаимодействия с ним.
Функции и методы
Почему у T и * T разные наборы методов?
Как сказано в спецификации Go,
набор методов типа T
состоит из всех методов
с ресивером типа T
,
в то время как соответствующий указатель
тип * T
состоит из всех методов с приемником * T
или Т
.Это означает, что набор методов * T
включает в себя T
,
но не наоборот.
Это различие возникает потому, что
если значение интерфейса содержит указатель * T
,
вызов метода может получить значение путем разыменования указателя,
но если значение интерфейса содержит значение T
,
не существует безопасного способа получения указателя вызовом метода.
(Это позволит методу изменять содержимое
значение внутри интерфейса, что не разрешено
спецификация языка.)
Даже в тех случаях, когда компилятор мог принять адрес значения
передать методу, если метод изменяет значение, то изменения
будет потеряно в звонилке.
Например, если метод Write
байт Буфер
использовал приемник значения, а не указатель,
этот код:
var buf bytes.Buffer io.Copy (buf, os.Stdin)
скопирует стандартный ввод в копию из buf
,
не в сам buf
.Это почти никогда не бывает желаемым поведением.
Что происходит с закрытием, работающим как горутины?
Некоторая путаница может возникнуть при использовании замыканий с параллелизмом. Рассмотрим следующую программу:
func main () { сделано: = make (chan bool) значения: = [] строка {"a", "b", "c"} for _, v: = диапазон значений { go func () { fmt.Println (v) сделано <- правда } () } // ожидаем завершения всех горутин перед выходом for _ = диапазон значений { <-делано } }
Можно ошибочно ожидать, что на выходе будет a, b, c
.Вместо этого вы, вероятно, увидите c, c, c
. Это потому что
каждая итерация цикла использует один и тот же экземпляр переменной v
, поэтому
каждое закрытие разделяет эту единственную переменную. Когда закрытие запускается, он печатает
значение v
во время выполнения fmt.Println
,
но v
могли быть изменены с момента запуска горутины.
Чтобы помочь обнаружить эту и другие проблемы до того, как они возникнут, запустите ветеринар
.
Чтобы привязать текущее значение v
к каждому закрытию при его запуске, один
должен изменять внутренний цикл для создания новой переменной на каждой итерации.Один из способов - передать переменную в качестве аргумента закрытия:
for _, v: = диапазон значений { go func ( u строка) { fmt.Println ( и ) сделано <- правда } ( против ) }
В этом примере значение v
передается в качестве аргумента в
анонимная функция. Затем это значение доступно внутри функции как
переменная u
.
Еще проще просто создать новую переменную, используя стиль объявления, который может кажется странным, но отлично работает в Go:
for _, v: = диапазон значений { v: = v // создаем новый 'v'.go func () { fmt.Println ( против ) сделано <- правда } () }
Это поведение языка, не определяющее новую переменную для каждая итерация, возможно, была ошибкой в ретроспективе. Это может быть рассмотрено в более поздней версии, но для совместимости не может быть изменен в Go версии 1.
Управляющий поток
Почему в Go нет оператора
?:
?В Go нет операции троичного тестирования. Вы можете использовать следующее, чтобы добиться того же результат:
if expr { n = trueVal } еще { n = falseVal }
Причина, по которой ?:
отсутствует в Go, заключается в том, что разработчики языка
видел, как эта операция слишком часто используется для создания непостижимо сложных выражений.Форма if-else
, хотя и длиннее,
бесспорно яснее.
Для языка требуется только одна условная конструкция потока управления.
Пакеты и тестирование
Как создать многофайловый пакет?
Поместите все исходные файлы для пакета в отдельный каталог. Исходные файлы могут по желанию ссылаться на элементы из разных файлов; есть нет необходимости в форвардных объявлениях или заголовочном файле.
Помимо разделения на несколько файлов, пакет будет скомпилирован и протестирован как однофайловый пакет.
Как мне написать модульный тест?
Создайте новый файл, заканчивающийся на _test.go
, в том же каталоге.
в качестве источников вашего пакета. Внутри этого файла import "testing"
и напишите функции вида
func TestFoo (t * testing.T) { ... }
Запустите go test
в этом каталоге.
Этот скрипт находит функции Test
,
создает тестовый двоичный файл и запускает его.
См. Документ «Как писать код Go»,
тестовый пакет
и подкоманда go test
для получения дополнительных сведений.
Где моя любимая вспомогательная функция для тестирования?
Стандартный пакет Go testing
упрощает написание модульных тестов, но в нем отсутствует
функции, предоставляемые в рамках тестирования других языков, такие как функции утверждения.
В предыдущем разделе этого документа объяснялось, почему Go
не имеет утверждений, и
те же аргументы применимы к использованию assert
в тестах.
Правильная обработка ошибок означает запуск других тестов после сбоя одного из них, поэтому
что человек, отлаживающий сбой, получает полное представление о том, что
неправильно.Для теста более полезно сообщить, что isPrime
дает неправильный ответ для 2, 3, 5 и 7 (или для
2, 4, 8 и 16), чем сообщить, что isPrime
дает неверное
ответ на 2, и поэтому тесты больше не проводились. Программист, который
запускает ошибку теста, возможно, не знаком с кодом, который не работает.
Время, потраченное на написание хорошего сообщения об ошибке, теперь окупается позже, когда
тестовые перерывы.
С этим связан и тот факт, что среды тестирования, как правило, превращаются в мини-языки. собственные, с условными выражениями, элементами управления и механизмами печати, но в Go уже есть все эти возможности; зачем их воссоздавать? Лучше писать тесты на Go; это на один язык меньше, чтобы учить, и Такой подход делает тесты простыми и понятными.
Если количество дополнительного кода, необходимого для написания
хорошие ошибки кажутся повторяющимися и непосильными, тест может работать лучше, если
управляемый таблицей, итерация по списку определенных входов и выходов
в структуре данных (Go имеет отличную поддержку литералов структуры данных).
Тогда работа по написанию хорошего теста и хороших сообщений об ошибках будет окупаться за счет многих
тестовые случаи. Стандартная библиотека Go полна наглядных примеров, например, в
тесты форматирования для пакета fmt
.
Почему в стандартной библиотеке нет
X ?Стандартная библиотека предназначена для поддержки среды выполнения, подключения к операционной системы и обеспечивают ключевые функции, которые многие Go требуются программы, такие как форматированный ввод-вывод и работа в сети. Он также содержит элементы, важные для веб-программирования, в том числе криптография и поддержка таких стандартов, как HTTP, JSON и XML.
Нет четкого критерия, определяющего, что включается, потому что для долгое время это была только библиотека Go.Однако есть критерии, которые определяют, что добавляется сегодня.
Новые дополнения к стандартной библиотеке редки, и планка для включение высокое. Код, включенный в стандартную библиотеку, требует больших затрат на текущее обслуживание. (часто несут не первоначальные авторы), подлежит обещанию совместимости с Go 1 (блокировка исправлений любых недостатков в API), и подлежит Go график выпуска, предотвращение быстрого доступа пользователей к исправлениям ошибок.
Большая часть нового кода должна находиться вне стандартной библиотеки и быть доступной.
с помощью инструмента go
иди и получи команду
.У такого кода могут быть свои сопровождающие, цикл выпуска,
и гарантии совместимости.
Пользователи могут найти пакеты и прочитать их документацию по адресу
godoc.org.
Хотя в стандартной библиотеке есть части, которым на самом деле не место,
например, журнал / системный журнал
, мы продолжаем поддерживать все в
библиотека из-за обещания совместимости с Go 1.
Но мы призываем большую часть нового кода жить где-нибудь в другом месте.
Реализация
Какая технология компилятора используется для создания компиляторов?
Для Go существует несколько производственных компиляторов и ряд других. в разработке для различных платформ.
Компилятор по умолчанию, gc
, включен в
Распространение Go как часть поддержки go
команда. Gc
изначально был написан на C
из-за трудностей начальной загрузки вам понадобится компилятор Go для
настроить среду Go.
Но все продвинулось вперед, и с момента выпуска Go 1.5 компилятор стал
программа Go.
Компилятор был преобразован с C на Go с использованием средств автоматического перевода, как
описано в этом проектном документе
и говорить.Таким образом, компилятор теперь является «самообслуживающимся», а это значит, что нам нужно было столкнуться с
проблема начальной загрузки.
Решение состоит в том, чтобы уже иметь работающую установку Go,
так же, как обычно при работающей установке C.
Рассказ о том, как создать новую среду Go из исходников
описан здесь и
здесь.
Gc
написан на Go с рекурсивным анализатором спуска
и использует собственный загрузчик, также написанный на Go, но
основанный на загрузчике Plan 9, для генерации двоичных файлов ELF / Mach-O / PE.
В начале проекта мы рассматривали возможность использования LLVM для gc
, но решил, что он слишком большой и медленный для соответствия
наши производственные цели.
Оглядываясь назад, более важно то, что начало LLVM сделало бы его
сложнее внедрить некоторые из ABI и связанных с ним изменений, таких как
управление стеком, которое требует Go, но не является частью стандарта
Настройка C.
Новая реализация LLVM
однако сейчас начинает объединяться.
Компилятор Gccgo
- это интерфейс, написанный на C ++.
с рекурсивным синтаксическим анализатором спуска, связанным с
стандартный бэкэнд GCC.
Go оказался прекрасным языком для реализации компилятора Go, хотя это не было его первоначальной целью. Отсутствие самостоятельного хостинга с самого начала позволило дизайну Go сконцентрируйтесь на своем первоначальном варианте использования, которым были сетевые серверы. Если бы мы решили, что Go должен скомпилировать себя на ранней стадии, мы могли бы закончился язык, ориентированный больше на создание компиляторов, Это достойная цель, но не та, которая была у нас изначально.
Хотя gc
не использует их (пока?), Нативный лексер и
парсер доступен в пакете go
а также есть встроенная программа проверки типов.
Как реализована поддержка времени выполнения?
Опять же из-за проблем с начальной загрузкой код времени выполнения изначально был написан в основном на C (с
крошечный бит ассемблера), но с тех пор он был переведен на Go
(за исключением некоторых битов ассемблера). Gccgo
во время выполнения поддержки использует glibc
.
Компилятор gccgo
реализует горутины, используя
метод, называемый сегментированными стеками,
поддерживается недавними модификациями золотого линкера. Gollvm
аналогично построен на соответствующем
Инфраструктура LLVM.
Почему моя обычная программа имеет такой большой двоичный файл?
Компоновщик в цепочке инструментов gc
по умолчанию создает статически связанные двоичные файлы.
Поэтому все двоичные файлы Go включают Go
время выполнения, а также информацию о типе времени выполнения, необходимую для поддержки динамических
проверка типов, отражение и даже трассировка стека во время паники.
Простая программа на языке C "hello, world", скомпилированная и скомпилированная статически с использованием
gcc в Linux составляет около 750 КБ, включая реализацию printf
.Эквивалентная программа Go с использованием fmt.Printf
весит пару мегабайт, но это включает
более мощная поддержка во время выполнения и информация о типах и отладке.
Программа Go, скомпилированная с помощью gc
, может быть связана с
флаг -ldflags = -w
для отключения генерации DWARF,
удаление отладочной информации из двоичного файла, но без
другая потеря функциональности.
Это может существенно уменьшить размер двоичного файла.
Могу ли я прекратить эти жалобы на мою неиспользованную переменную / импорт?
Наличие неиспользуемой переменной может указывать на ошибку, в то время как неиспользованный импорт просто замедляет компиляцию, эффект, который может стать существенным по мере того, как программа накапливает код и программисты с течением времени.По этим причинам Go отказывается компилировать программы с неиспользуемыми переменные или импорт, обменять краткосрочное удобство на долгосрочную скорость сборки и ясность программы.
Тем не менее, при разработке кода обычно создаются такие ситуации. временно, и может раздражать необходимость их отредактировать до того, как программа будет компилироваться.
Некоторые просили параметр компилятора, чтобы отключить эти проверки. или, по крайней мере, свести их к предупреждению. Однако такой возможности не было, поскольку параметры компилятора не должны влиять на семантику язык и поскольку компилятор Go не выдает предупреждения, а только ошибки, препятствующие компиляции.
Есть две причины отсутствия предупреждений. Во-первых, если это стоит жаловаться, стоит исправить в коде. (А если это не так стоит исправить, об этом не стоит упоминать.) Во-вторых, наличие компилятора генерировать предупреждения побуждает реализацию предупреждать о слабых случаи, которые могут сделать компиляцию шумной, маскируя реальные ошибки, которые должен быть исправлен.
Однако исправить ситуацию легко. Используйте пустой идентификатор чтобы неиспользуемые вещи сохранялись, пока вы разрабатываете.
импорт "неиспользованный" // Это объявление отмечает импорт как используемый путем ссылки на // товар из пакета. var _ = unused.Item // ЗАДАЧА: Удалить перед фиксацией! func main () { debugData: = debug.Profile () _ = debugData // Используется только во время отладки. .... }
В настоящее время большинство программистов Go используют инструмент, goimports который автоматически перезаписывает исходный файл Go для правильного импорта, устранение проблемы неиспользованного импорта на практике. Эта программа легко подключается к большинству редакторов для автоматического запуска при записи исходного файла Go.
Почему мое антивирусное программное обеспечение считает, что мой дистрибутив Go или скомпилированный двоичный файл заражен?
Это обычное явление, особенно на компьютерах с Windows, и почти всегда ложное срабатывание. Коммерческие программы сканирования на вирусы часто сбивают с толку из-за структуры двоичных файлов Go, которые они видят не так часто, как компилированные с других языков.
Если вы только что установили дистрибутив Go, и система сообщает, что он заражен, это определенно ошибка.Чтобы быть действительно тщательным, вы можете проверить загрузку, сравнив контрольную сумму с контрольной суммой страница загрузок.
В любом случае, если вы считаете, что отчет содержит ошибку, сообщите об ошибке поставщику вашего антивирусного сканера. Возможно, со временем антивирусные сканеры научатся понимать программы Go.
Производительность
Почему Go плохо справляется с тестом X?
Одна из целей разработки Go - приблизиться к производительности C для сопоставимых программ, но в некоторых тестах он работает довольно плохо, в том числе в нескольких в голанге.org / x / exp / стрелять. Самый медленный зависит от библиотек, для которых версии сопоставимой производительности недоступны в Go. Например, pidigits.go зависит от математического пакета с множественной точностью, а C версии, в отличие от Go, используют GMP (т.е. написано на оптимизированном ассемблере). Тесты, зависящие от регулярных выражений (regex-dna.go, например) по сути сравнивают собственный пакет регулярных выражений Go с зрелые, оптимизированные библиотеки регулярных выражений, такие как PCRE.
Тестовые игры выигрывают благодаря обширной настройке, и версии Go большинства тестов требуют внимания.Если вы измеряете сопоставимый C и программы Go (reverse-complement.go является одним из примеров), вы увидите, что эти два языка намного ближе по сырой производительности чем этот люкс мог бы указать.
Тем не менее, есть возможности для улучшения. Компиляторы хороши, но могут быть лучше, многим библиотекам требуется большая работа по повышению производительности, а сборщик мусора еще недостаточно быстро. (Даже если бы это было так, стараясь не генерировать ненужные мусор может иметь огромное влияние.)
В любом случае Го часто может быть очень конкурентоспособным.Произошло значительное улучшение производительности многих программ. по мере развития языка и инструментов. См. Сообщение в блоге о профилирование Go программы для информативного примера.
Отличия от C
Почему синтаксис так отличается от C?
Помимо синтаксиса объявления, различия не являются существенными и коренными. от двух желаний. Во-первых, синтаксис должен казаться легким, но без лишнего много обязательных ключевых слов, повторений или арканов. Во-вторых, язык был разработан, чтобы его было легко анализировать и может быть проанализирован без таблицы символов.Это значительно упрощает для создания таких инструментов, как отладчики, анализаторы зависимостей, автоматизированные экстракторы документации, плагины IDE и т. д. C и его потомки, как известно, трудны в этом отношении.
Почему декларации перевернуты?
Они идут в обратном направлении, только если вы привыкли к C.В C идея состоит в том, что
переменная объявляется как выражение, обозначающее ее тип, который является
хорошая идея, но грамматика типов и выражений не очень хорошо сочетается и
результаты могут сбивать с толку; рассмотреть указатели на функции.Идти в основном
разделяет синтаксис выражения и типа, что упрощает работу (использование
префикс *
для указателей - исключение, подтверждающее правило). В C,
декларация
int * a, b;
объявляет a
как указатель, но не b
; в Go
var a, b * int
объявляет оба указателями. Это более четкое и регулярное.
Кроме того, в краткой форме объявления : =
утверждается, что полная переменная
объявление должно иметь тот же порядок, что и : =
, поэтому
var a uint64 = 1
имеет тот же эффект, что и
а: = uint64 (1)
Синтаксический анализ также упрощается за счет наличия четкой грамматики для типов, которые
это не просто грамматика выражений; такие ключевые слова, как func
и чан
держать вещи в ясности.
См. Статью о Синтаксис объявления Go Больше подробностей.
Почему нет арифметики указателей?
Безопасность. Без арифметики указателей можно создать язык, который никогда не может получить незаконный адрес, который успешно неправильно. Компилятор и аппаратные технологии продвинулись до точка, в которой цикл с использованием индексов массива может быть таким же эффективным, как и цикл используя арифметику указателей. Кроме того, отсутствие арифметики указателей может упростить реализацию сборщика мусора.
Почему
++
и -
являются операторами, а не выражениями? А почему постфикс, а не префикс? Без арифметики указателей удобное значение пре- и постфикса
операторы инкремента отбрасываются. Удалив их из выражения
иерархии в целом, синтаксис выражений упрощен, а беспорядочный
проблемы, связанные с порядком вычисления ++
и -
(рассмотрим f (i ++)
и p [i] = q [++ i]
)
также устраняются.Упрощение
значительный. Что касается постфикса и префикса, то любой из них будет работать нормально, но
постфиксная версия более традиционна; настаивание на префиксе возникло
с STL, библиотекой для языка, имя которого, по иронии судьбы, содержит
постфиксное приращение.
Почему есть фигурные скобки, но нет точки с запятой? И почему я не могу поставить открытие скобка на следующей строке?
Go использует фигурные скобки для группировки операторов, синтаксис, знакомый программисты, работавшие с любым языком семейства C.Однако точки с запятой предназначены для парсеров, а не для людей, и мы хотели устраните их в максимально возможной степени. Для достижения этой цели Go заимствует уловка от BCPL: точки с запятой, разделяющие операторы, находятся в формальной грамматики, но вводятся автоматически, без просмотра вперед лексический анализатор в конце любой строки, которая может быть концом оператора. Это очень хорошо работает на практике, но приводит к тому, что подтяжка стиль. Например, открывающая скобка функции не может появляются в отдельной строке.
Некоторые утверждали, что лексер должен смотреть вперед, чтобы разрешить
скоба, чтобы жить на следующей строке. Мы не согласны. Поскольку имеется в виду код Go
для автоматического форматирования гофмт
, г. какой-то стиль должен быть выбран. Этот стиль может отличаться от того, что
вы использовали C или Java, но Go - другой язык и
Стиль gofmt
ничем не хуже любого другого. Более
важно - гораздо важнее - преимущества одного,
программно обязательный формат для всех программ Go значительно перевешивает
любые предполагаемые недостатки определенного стиля.Также обратите внимание, что стиль Go означает, что интерактивная реализация
Go может использовать стандартный синтаксис по одной строке за раз без специальных правил.
Зачем делать сборку мусора? Не будет ли это слишком дорого?
Одним из важнейших источников учета в системных программах является управление сроками жизни выделенных объектов. В таких языках, как C, где это делается вручную, это может потребовать значительного количества времени программиста и часто причина пагубных ошибок. Даже в таких языках, как C ++ или Rust, которые предоставляют механизмы чтобы помочь, эти механизмы могут оказать значительное влияние на дизайн программного обеспечения, часто добавляющие накладные расходы на программирование собственноручно.Мы сочли необходимым устранить такие накладные расходы программиста и успехи в сборке мусора технологии за последние несколько лет вселили в нас уверенность в том, что может быть реализован достаточно дешево и с достаточно низкой задержка, что может быть жизнеспособным подходом для сетевых системы.
Большая часть сложности параллельного программирования уходит корнями в проблему времени жизни объекта: поскольку объекты передаются между потоками, это становится громоздким чтобы гарантировать их безопасное освобождение. Автоматическая сборка мусора значительно упрощает написание параллельного кода.Конечно, реализация сборки мусора в параллельной среде - это само по себе вызов, но встретить его один раз, а не каждый программа помогает всем.
Наконец, помимо параллелизма, сборка мусора делает интерфейсы проще, потому что им не нужно указывать, как ими управлять памятью.
Это не означает, что недавняя работа над языками как Rust, который привносит новые идеи в проблему управления ресурсы неправильно направляются; мы поощряем эту работу и рады видеть как это развивается.Но Go использует более традиционный подход, обращаясь к время жизни объекта через сборка мусора, и только сборка мусора.
Текущая реализация - это сборщик меток и разверток. Если машина является многопроцессорной, сборщик работает на отдельном процессоре. core параллельно с основной программой. Крупные работы на коллекторе в последние годы позволили сократить время пауз. часто до субмиллисекундного диапазона, даже для больших куч, почти все, кроме устранения одного из основных возражений против сборки мусора в сетевых серверах.Продолжается работа по совершенствованию алгоритма, сокращению накладных расходов и задержка и изучить новые подходы. 2018 год Основной доклад ISMM Рик Хадсон из команды го описывает достигнутый прогресс и предлагает некоторые будущие подходы.
Что касается производительности, имейте в виду, что Go дает программисту значительный контроль над компоновкой и распределением памяти, гораздо больше, чем типично для языков со сборкой мусора. Внимательный программист может уменьшить значительные накладные расходы на сборку мусора при правильном использовании языка; см.