Програма за изучаване на езика за програмиране go. Golang – езикът Go – защо е необходим и какво пише в него? Минуси на езика Go

Стефан Нилсон преподава компютърни науки в Кралския технологичен институт в Стокхолм и пише много за езика Go. Предлагаме ви превод на неговата статия Защо да отидете? - Ключови предимства, които може би сте пренебрегнали, където той говори за основните предимства на езика. Статията е насочена към читатели, които вече са запознати с основите на програмирането, включително Java и/или Python.

Изборът на език за програмиране не е лесен. Индивидуалните предимства могат да бъдат очарователни в началото, докато идентифицирането на недостатъците изисква време и опит.

Go е основният ми език от 2012 г. Преди това, от 1998 г., използвах Java, а още по-рано - C. Използвам Python основно за преподавателската си работа.

Започнах да програмирам през 1978 г. Тогава писах за калкулатора TI-57, с неговата програмна памет за 50 стъпки и 8 регистъра.

минимализъм

отивам- минималистичен език, което е (в по-голямата си част) много добро.

Визия за бъдещето

В Go липсват редица функции, общи за други съвременни езици.

Друг пример: Go няма да компилира програма, ако изисква някои пакети (чрез импортиране), но всъщност не ги използва в кода. Този подход подобрява яснотата на кода и в дългосрочен план неговата производителност.

Подозирам, че създателите на Go умишлено сложнонякои неща. Например, изискват се много усилия, за да се хване изключение (паника). Освен това, за да преминете над безопасността на типа, ще трябва да маркирате кода си с ключовата дума unsafe.

Сравнение с Python

В Python кодовият фрагмент del a[i] премахва елементите с индекс i от списъка a. Този код, разбира се, Прочети, но не прозрачен: лесно е да се пренебрегне, че времевата сложност на алгоритъма е представена като O(n), където n е броят на елементите в списъка.

Go няма такъв полезна функция. Това е не е толкова удобно, но по-прозрачен. Ако копирате елемент от списъка, трябва изрично да го посочите в кода си. Вижте пример за код: 2 начина за премахване на елемент от срез в Go. Но е възможно и по-лесно - с помощта на append .

Сравнение с Java

Прозрачността на кода не е пресилен проблем. Ето няколко примера за това как правилата за инициализация на пакета и изпълнение на код на Go улесняват поддържането и прецизирането на проект:

  • Кръговите зависимости могат да доведат до нежелани последствия. За разлика от Java кода, Go програма с циклична инициализация няма да се компилира.
  • Програма Go излиза само от основната функция. Приложението Java се затваря, когато всички потребителски нишки, които не са демон, прекратят.

Това означава, че за да разберете особеностите на това как работи едно Java приложение, трябва да изучите големи фрагменти от неговия код. Това може да не е възможно изобщо, ако използвате библиотеки на трети страни.

Съвместимост

Езикът, който е предмет внезапни промениили губи подкрепа, може да съсипе вашия проект.

За първата версия на Go гаранциите за съвместимост за „ядрото“ на езика и стандартните библиотеки бяха накратко посочени: Go програмите, които работят днес, трябва да работят с бъдещи версии на Go 1. Досега обратната съвместимост беше безупречна.

Go е проект с отворен код с лиценз, подобен на BSD, който позволява комерсиална употреба, модификация, разпространение и лична употреба.

Правата на интелектуална собственост принадлежат

За съжаление на хоризонта се събират облаци. Причината за това е съдебно дело между Oracle America и Google относно естеството на компютърния код, авторските права и новия модел на лицензиране на Java на Oracle.

производителност

Отвън Go е сдържан, но под капака има добре смазан двигател.

Безсмислено е да обсъждаме представянето извън контекста. Параметрите на програмата като време за изпълнение и консумация на памет са силно зависими от алгоритми, структури от данни, входни данни, умения на програмиста, операционна системаи "желязо".

Въпреки това, производителността може да бъде значително засегната език, среда за изпълнениеи стандартни библиотеки. Всичко това се отнася до задачи на високо ниво и архитектурни решения. За по-задълбочено разбиране на внедряването и производителността на компилатора, прочетете Go FAQ.

Преди всичко, иди- компилиранезик. Готово за стартиране Go приложение обикновено изглежда като единичен изпълним файл без отделни DLL или виртуални машини за директно разгръщане.

Обем и скорост на генериране на машинен кодзависи от целевата архитектура. Генерирането на Go код е красиво и поддържа всички основни ОС (Linux, macOS, Windows) и архитектури (Intel x86/x86-64, ARM64, WebAssembly, ARM и др.). Следователно можете да очаквате производителност на ниво C ++ или Java от горутинни приложения. Отплатата за интерпретирания код на Python може да бъде огромна.

Go има събирач на боклук, което предотвратява изтичане на памет. Освен това забавянето в работата на колектора е минимално. Всъщност може дори да не забележите, че "нишката за боклук" тече.

Почти всички стандартни библиотекиизпълнени с много високо качество: техният код е оптимизиран от ефективни алгоритми. Например, регулярните изрази в Go работят толкова добре, че времето за изпълнение е пряко свързано с количеството вход. За съжаление нещата са различни с Java и Python.

Скорост на сглобяванев абсолютно изражение сега е доста добре. По-важното е, върви проектиранитака че да се опрости компилирането и анализа на зависимостите. Това ви позволява да създавате лесно мащабируемирешения за развиващи се проекти.

Какво пише на него?

И какво можеш да напишеш?

Всичко. Всъщност всичко, но поради предимствата си, той е много популярен за разработване на сървърна страна (бекенд).

Струва ли си да се учи?

Въпросът е риторичен. От гледна точка на възможността за закупуване, почти няма готово търсене за него, поради младостта и липсата на популяризиране. Така че има смисъл:

  1. За себе си, вашето стартиране
  2. Продайте готовия продукт
  3. Завършете поръчката, ако предимствата на този език отговарят на клиента (ще трябва да обясните/убедите)

Или скоро ще изчезне?

Както вече споменахме, той не може да изчезне, т.к. отворен код. Тези. никой няма да ви отнеме написаното в него, развитието/поддръжката ще се влоши най-много, което е трудно да се повярва, защото езикът има много значителни предимства.

Плюсове или "защо избрах Go"

производителност

По отношение на производителността за мрежата (готови рамки), Go губи само от Java и C / C ++ и наравно с node.js. В същото време консумацията на ресурси е значително по-ниска от тази на Java, а производителността е много по-висока от тази на Python / Ruby.

Многонишковост

В същото време той има просто страхотен многонишков модел в сравнение с тях. Досега това е най-доброто, което съм виждал за многонишков/асинхронен. В същото време той поддържа и класически модели като мютексове и обратни извиквания.

Простота

Много е лесно да се научи. Струва ми се дори елементарно, особено ако има основа от Python / JavaScript. Има и доста интересен модел на наследяване, който, струва ми се, е по-прозрачен от класическия ООП, но малко необичаен в началото.

Надеждност

Този език е компилиран и статично въведен. Това дава възможност за идентифициране на много грешки много преди производството. Например, такива грешки в Python се откриват само чрез директно тестване и ако няма тестове, тогава има много шансове да извадите системата. Това веднага се изключва на етапа на компилация.

Скорост на компилация

И накрая, една от основните характеристики - не се страхувайте от въвеждане и компилация. В 145% от случаите не е нужно да декларирате типа на променливата в кода - тя се задава автоматично, когато й се присвоява стойност. Също така не е необходимо предварително да се декларират променливи.

Е, компилацията е основната силна страна. Времето за компилиране е основният фокус на езиковото развитие. Не се различава от времето на стартиране на интерпретирания език. Тези. система, написана на go от некомпилирани източници, работи с приблизително същата скорост като система с подобна сложност, написана на интерпретиран език.

Обща сума

Тези. имаме плюсове от два свята - скоростта на компилиране/стартиране на интерпретирания и надеждността на компилирания език. Плюс производителност, мулти-парадигма (можете да пишете във функционален стил), простота и ниска консумация на ресурси.

Дали те устройва не е аз да решавам. Устройва ме и го смятам за много добър избор за високонатоварени услуги (и не само).

Go е език за програмиране, разработен от Google Corporation. Често се нарича още "Голанг" - съкратено от "език на Google". Това е компилиран и многонишков език, който беше пуснат през ноември 2009 г., като най-новата версия 1.6 е от февруари 2016 г. Един от ключовите хора, участвали в създаването на Go, е Роб Пайк, известен разработчик на езици за програмиране и операционни системи, който в момента работи в Google. Говорейки на една от конференциите, той отбеляза, че езикът Go е опит за възприемане на най-добрите аспекти на езици като C++ и Java.

В тази статия ще се опитаме да разберем колко популярен е езикът Go, дали има перспективи за развитие и какво мислят самите програмисти за този език.

Приложение

Езикът Go е проектиран като език за създаване на различни високоефективни програми, но повечето програмисти са съгласни, че той е най-подходящ за създаване на уеб приложения (като бек-енд). В същото време Go ви дава възможност да пишете други проекти, например Docker, InfluxDB и Kubernetes. Всъщност използването на езика Go е ограничено до три основни области: софтуер, конзолни помощни програми и бекенд.

Една от отличителните черти на езика е оригиналната система от типове: в езика няма наследяване (един от принципите на обектно-ориентираното програмиране). Go също използва съкратен синтаксис за дефиниране на променливи и синтаксис на анонимна функция.
Друга особеност на този език е паралелизмът, което означава, че всяка функция може да се изпълнява едновременно с друга.

Тъй като Go е един от младите езици за програмиране, има редовни дискусии относно целесъобразността на използването му.

Предимства на езика Go

Езикът Go има няколко положителни характеристики, подчертани от програмисти, които пишат на него.

Първо, е неговата простота. Езикът Go е разработен като заместител на C: неговата висока производителност е почти сравнима с езика C, но по-простият му синтаксис прави възможно разработването на приложения много по-бързо (като в Python, например). Въпреки това, много разработчици научават този език след Python или PHP или използват два езика във връзка (Python/Go и PHP/Go). Опростеният синтаксис улеснява не само писането на собствен код, но и четенето на код, написан от други програмисти, което е особено важно при работата в екип. Тази характеристика на Go от своя страна води до друг важен факт: бързото овладяване на Go ви позволява да прехвърлите вниманието си от изучаването на самия език към изучаването на програмиране като цяло.

Програмистите непрекъснато сравняват езика Go с други езици: това се доказва в негова полза от факта, че например PHP има 67 ключови думи, докато Go има само 25.

Тук е необходимо да се отклоним и да кажем, че желанието за създаване на прост език за програмиране не се е родило случайно сред разработчиците на Google: първоначално те са замислили Go като бързо усвоен език, който няколко не много опитни програмисти могат лесно да научат, за да напишат след това някои приложение заедно. Ето защо някои хора смятат Go за език, подходящ за големи корпорации, където много различни хора ще участват в разработването на продукти. Както бе отбелязано по-горе, прост и разбираем синтаксис означава, че програмистите на Go не трябва да въвеждат никакви други стандарти, нотация или коментари - те ще разберат перфектно кода на другия без това. Многословието на Go радва някои разработчици и разочарова други, но това прави кода на Go толкова лесен за четене.

Ето защо някои компании (например CrowdStrike) умишлено преминават от други езици за програмиране към Go, за да разширят по-лесно пула от своите разработчици в бъдеще.

Второ, Go има голям бройбиблиотеки, благодарение на които можете да изпълнявате почти всяка задача. Много може да се направи, като се използва само стандартната библиотека на Go, която е лесна за четене, а също и различна. добро качествои скорост. Специално внимание заслужава ефективното взаимодействие с C библиотеките; някои посочват, че Go библиотеките всъщност са само обвивки за C библиотеки.

Трето, Go е компилиран език, на който можете бързо да напишете необходимото приложение. Go има същото силно статично въвеждане като Pascal, но в същото време има много по-приложен характер (и това го прави подобен на Python). Тук е необходимо да се отбележи високата производителност на Golang, която е типична за компилираните езици. Също така в Go кросплатформеността е значително улеснена.

Невъзможно е да не се отбележи ясният фокус на езика Go: за разлика от PHP, който се използва за писане на големи проекти, Go е по-скоро предназначен за малки услуги, които трябва да бъдат написани и внедрени бързо, но които трябва да бъдат изключително надеждни (т.е. -наречен стабилен софтуер).

Внедряването на Go приложение също изглежда много по-лесно от внедряването на PHP приложение. Чрез програмиране в Go можете да създавате артефакти за всички операционни системи или процесорни архитектури, без да се налага да инсталирате Go на сървърите, които използвате.

Синтаксисът на Go може да е непознат за тези, които преди това са програмирали в PHP или Python. Ако разгледаме Go кода в сравнение с PHP, тогава Go няма обекти или класове, но има структура, или по-скоро тип, който съдържа наименувани полета:

Тип Circle struct ( x, y, r float64 )

Друга причина, поради която Go набира все по-голяма популярност, е наличието на go fmt, инструмент, който помага за стандартизиране на кода. И използването на go vet ще ви помогне да намерите възможни проблемив код. С други думи, авторите на езика Go се опитаха да опростят максимално задачата за разработване на приложения на този език, особено за начинаещи.

Ето защо мнозина в момента смятат Go за един от най-добрите езици за програмиране и се препоръчват да го изучават не само за студенти, но и за ученици. Между другото, вече е имало такъв прецедент: учител научи няколко 11-годишни ученици да пишат и разбират код на такова ниво, че да могат да напишат фрактален генератор на Манделброт. И най-важното, отне му само 12-13 часа, за да направи това!

Минуси на езика Go

Сегашното ниско разпространение на Go често се посочва като отрицателна страна - наистина има много по-често срещани езици за програмиране, които се използват за изпълнение на повечето задачи. Това означава ли, че Go не си струва да се учи? Въобще не. Има много корпорации, които използват езика Go в своето развитие. На първо място, разбира се, това е Google Inc., както и Basecamp, BBC Worldwide, Canonical, DigitalOcean, Dropbox, eBay, Yahoo и много други компании по света. Следователно този език за програмиране определено има перспективи. Разбира се, Go програмистите може да са по-малко търсени от, например, PHP разработчиците, но конкуренцията е по-ниска, което означава, че има по-голям шанс да намерите интересна и добре платена работа.

Тези, които се опитват да предскажат бъдещето на езика Go, говорят и за друг недостатък, който всъщност е обратното на предишната точка: поради лекотата на езика и следователно ниския праг за влизане, броят на хората, програмиращи в Go, ще расте експоненциално, докато кодът за качество и самите проекти ще оставят много да се желае. Подобна ситуация се случи и с PHP в началото на 21-ви век, когато много начинаещи програмисти започнаха да пишат на този език, без да се притесняват особено за ефективността на своя код (и готови да получат малка такса за работата си). Разликата между PHP и Go в момента е, че PHP в крайна сметка се превърна в пълноценен език с богата инфраструктура и много рамки, без да знаете които трудно можете да намерите Добра работа. Go се позиционира като прост език, така че перспективите за неговото развитие не са много дефинирани.

В рамките на тази статия няма да се спирам на чисто технически точки, които предизвикват недоумение сред програмистите, тъй като това са абсолютно субективни впечатления. Често възникват въпроси от системата от типове, липсата на генерици, претоварването на оператора, възможността за разширяване на ключови думи и много други. Разбира се, Go не е перфектен език и когато го запознаят за първи път, някои може да не харесат разликите с техния по-познат език за програмиране.

Заключение

Езикът Go е все още достатъчно млад, за да говори за определена гледна точка. Въпреки това, много хора вече възприемат Go като модерен или дори авангарден език, който допринася за развитието на езиците за програмиране като цяло. Дори и да сте фен на определен език за програмиране от дълго време, Go има много нови инструменти, които ще разширят хоризонтите ви или дори ще ви накарат да искате да разработвате приложения в Go. Правейки това, ще отделите минимално време за запознаване със синтаксиса на този език (до няколко дни), така че дори ако очакванията ви относно Go не са изпълнени, ще получите интересно и ценно изживяване.

Склонни сме да мислим, че няма наистина универсални езици за програмиране. Когато имаме нужда от ефективност, пишем на C и се примиряваме с неговите ограничения. Когато е необходима скорост на разработка, ние кодираме на Python и очакваме да получим бавен код. Erlang ви позволява да създавате силно паралелни разпределени приложения, но е много трудно да се вместят в съществуващи проекти. Езикът Go напълно нарушава тази система на мислене, комбинирайки предимствата на много езици и освобождавайки програмистите от техните недостатъци.

Когато преди десет години Кен Томпсън, който участва активно в разработването на езика C, беше попитан какво би направил този език по това време, той отговори, че езикът ще бъде подобен на Limbo. Мина много време и Томпсън, заедно с друг автор на езика C, Роб Пайк, участва в създаването на Go - езикът, който се превърна в преосмисляне и последващо развитие на Limbo. Go беше представен на света на 10 ноември 2009 г. и почти веднага стана бестселър. Имената на автори, известни със създаването на операционната система UNIX, езика за програмиране C и кодирането UTF-8, и покровителството на Google, в чиито лаборатории е създаден езикът, дадоха страхотен старт на Go. Въпреки това, дори това не би позволило на езика да оцелее дълго, ако не можеше да предложи на програмистите нещо наистина ново – нещо, което би опростило живота им и би направило Go наистина незаменим. И това „нещо“ беше в езика. В големи количества.

Xi от днес

Създателите на Go позиционират своето поколение като системен език, който съчетава ефективността и скоростта на изпълнение на код, написан на C, с лекотата на разработка в скриптови езици от по-високо ниво и дори с вградени инструменти за паралелно програмиране. В същото време външно Go наподобява някаква странна смесица от синтаксиса на езиците C, Pascal и ADA, което, съчетано с горното описание, създава доста силно усещане за улов, почти същото като когато чуете за ново мега-разработка на ученици от Пятигорск. Той обаче бързо отшумява, когато започнете да учите език, и изчезва напълно, когато разберете защо Go стана такъв, какъвто е.

Go се основава на три основни идеи:

  1. Гарантирана висока скорост на компилиране и производителност на приложението.
  2. Лесна разработка и поддръжка на приложения, присъщи на скриптовите езици от високо ниво.
  3. Вградени инструменти за паралелно програмиране, които ви позволяват да използвате всички налични ядра на съвременните процесори.

Какво всъщност означава всичко това? Нека се заемем с всяка една от точките.

производителност

Дори една много проста референтна реализация на компилатора Go може да генерира изненадващо бърз код за част от секундата, чиято скорост на изпълнение ще бъде сравнима със скоростта на кода, написан на езици като C и C ++. В същото време, за разлика от своите предшественици, компилаторът Go гарантира проверка на типа, а полученият код получава вграден колектор за боклук и собствен механизъм за паралелизиране.

От самото начало езикът е проектиран така, че да бъде лесно разбираем и лесно „смилаем“ не само за човек, но и за машина. Много синтактични и архитектурни елементи на Go бяха замислени, ако не с основната цел, то поне с оглед на възможността за лесния им анализ от програма, било то компилатор, дебъгер или дори среда за разработка. Езикът се оказа много ясен и не позволява неочевидност и противоречиви места, които биха могли да объркат компилатора (език C ++ е ярък пример за такъв неочевиден синтаксис и обща механика, които карат главите на програмистите да се пукат и компилаторът бавно се плъзга на място).

Много други елементи на езика, които не са пряко свързани със синтаксиса, също са оптимизирани предварително. Например езикът няма механизъм за имплицитно преобразуване на типове, който предпазва програмиста от грешки и прави компилатора по-опростен. Езикът няма пълноценна реализация на класове с тяхното наследяване и полиморфизъм. Машината за паралелно програмиране използва собствена реализация на нишки във всяка програма, което прави нишките толкова лесни за създаване, че е почти нищо за създаването им. Вграденият боклук също е много пъргав, просто няма елементи в езика, които биха могли да усложнят работата му.

Go се предлага стандартно с плъгини за всички популярни среди за програмиране, включително Vim.

Лесна разработка и поддръжка

Go е системен език, което обаче не му пречи да бъде на достатъчно високо ниво, за да предостави на програмиста всичко необходимо за удобно и бързо кодиране. Езикът включва такива конструкции от високо ниво като асоциативни масиви и низове (които могат да се сравняват, копират, изчисляват дължината, нарязват). Той разполага със средствата да създава свои собствени типове данни (подобно на класовете на други езици), средствата за създаване на нишки и обмен на данни между тях и, разбира се, липсват указатели, които могат да се отнасят до всяко място в паметта (свиване на стека в програма, написана на Go, невъзможна по принцип). Основното обаче, което дава Go на програмиста, е самата простота и очевидност на синтаксиса, за който говорихме в предишния раздел. В този смисъл Go е много подобен на Pascal, Modula и Oberon: почти всеки синтактичен елемент на езика следва обща логика и може да бъде интерпретиран изрично и безпогрешно, независимо от позицията му в кода. Например, просто е невъзможно да се направи известната грешка при декларирането на променливи, описана във всички ръководства за стила на кодиране на езика C, в Go:

int* a, b; // В C и C++ "a" ще бъде указател, но "b" не
var a, b *int; // В Go и двете променливи ще бъдат указатели

Go е език, създаден от програмисти за програмисти. Това се проявява във всичко, от рамкиране на блокове от код в стил C, имплицитни декларации на тип, без да се налага да се поставя точка и запетая след всеки израз и завършва с архитектурни решения като липса на механизъм за изключения и пълноценни класове (те са създадени за опростяване на живота, но вместо това води до замъгляване на кода). Основната идея на езика е да бъде инструмент, който ви позволява да пишете програми, вместо да мислите дали изобщо ще работят (тази черта е присъща на C и в още по-голяма степен на C ++).

Инструменти за паралелно програмиране

Вградената паралелност е най-силната характеристика на Go и тя просто няма равен сред езиците с общо предназначение (с изключение на Limbo, но е свързана с Inferno OS). И предимството тук е не толкова, че тези инструменти са вградени в самия език, а че имплементират много прост и ефективен модел, който напълно следва теорията на взаимодействащите последователни процеси (CSP). Читателите, запознати с Occam и Limbo, трябва да имат добро разбиране за всички предимства на CSP, но за останалото ще обясня. Вместо да създава градина от нишки, ключалки, мътекси и други системи за синхронизация, които правят едновременното програмиране мъчително и водят до многостранични книги за писане на многонишкови приложения, авторът на CSP Тони Хоар предлага прост и елегантен решение: оставете приложението по всяко време да създаде нова нишка, която може да комуникира с родителя и други нишки чрез изпращане на синхронни съобщения.

В Go тази идея изглежда така:

  1. Създайте променлива на канала.
  2. Дефиницията на функция, която приема променлива на канал като аргумент и в тялото си съдържа код, който трябва да се изпълни в отделна нишка. Накрая функцията трябва да изпрати резултата от изпълнението си на тръбата (това се прави с помощта на специален оператор).
  3. Изпълнение на функция в отделна нишка с ключова дума"отивам".
  4. Четене от канал.

Функцията се разклонява от основната нишка на изпълнение, която в този момент преминава към изчакване на данни в канала, резултатът от изпълнението на функцията се изпраща към канала и основната нишка го получава. Просто, нали? Но как ще изглежда в кода?

Пример

Един от любимите ми примери за силата на езика Go е внедряването на таймер, който работи на отделна нишка и "чука" основната нишка на равни интервали, през които тя спи. Кодът за тази програма, написан на един от "класическите" езици за програмиране, би изглеждал тромав и объркващ, но Go ви позволява да го поддържате прост и красив.

Нашият програмен код:

1 пакет основен
2
3 импорт "време"
4 импортиране на "fmt"
5
6-функционален таймер (ch chan низ, ns, count int) (
7 за j:= 1; j<= count; j++ {
8 време. Спящ режим(int64(ns))
9, ако j == брои(
10 fmt.Printf(" Изпращане на последно съобщение...n")
11 часа<- "стоп!"
12) друго (
13 fmt.Printf(" Изпращане...n")
14.00 ч<- "продолжаем"
15 }
16 fmt.Printf(" Изпратено! n")
17 }
18 }
19
20 функции main() (
21 вар низ низ
22
23 ch:= make(chan низ)
Таймер за 24 хода (ch, 1000000000, 10)
25
26 за (
27 fmt.Printf("Приемам...n")
28 стр =<-ch
29 ако str == "стоп!" (
30 fmt.Printf("Получих последно съобщение, напускам.n")
31 връщане
32) друго (
33 fmt.Printf("Прието!n")
34 }
35 }
36 }

Най-простата реализация на тази програма ще отнеме петнадесет реда, но аз нарочно я усложних, като добавих терминален изход и условни изрази. Те ще ви помогнат да разберете общия синтаксис на езика и как работи планировчикът на нишки Go. Резултатът от командата е показан на екранната снимка.

Резултатът от програмата след пет повторения на цикъла

На пръв поглед списъкът е много подобен на кода на програма, написана на C, C ++ или дори Java, но при по-внимателно разглеждане разликите стават видими - Go наследи само основния синтаксис от C, докато повечето от ключовите думи и речникът се промени. Изходният код започва с ключовата дума пакет, последвана от името на пакета, към който принадлежи кодът. Всички стартирани от потребителя програми трябва да имат име main, докато библиотеките могат да имат произволно име, което ще се използва за достъп до функциите и променливите след импортирането. В този случай, за да се отбележи дали дадена функция или променлива трябва да се експортира, се използва главни букви: всички обекти, чиито имена започват с главна буква, ще бъдат експортирани, останалите ще останат частни.

Редове 3 и 4 импортират пакетите time и fmt, чиито функции ще ни трябват по-късно. Импортирането на пакети в много отношения е много подобно на включването на заглавни файлове в програма, както се прави в C и C++, с изключението, че Go първо наблюдава пространството от имена и всички импортирани функции, променливи и типове данни ще бъдат с префикс с името на пакета, и второ, не изисква самите заглавни файлове. Без да се забърквате със заглавки и пространства от имена!

Ред 6 започва описанието на функцията timer() за нашия основен актьор. В следващия код той ще бъде изпратен в отделна нишка и ще прекарва по-голямата част от времето в сън, а когато се събуди, ще докладва на основната нишка. За да направи това, той се нуждае от достъп до тръба, така че първият аргумент на функцията е ch от тип "string pipe". Тя също така трябва да знае колко дълго може да спи и колко пъти може да спи. Следователно вторият и третият аргумент са ns и броят от тип int. Обърнете внимание на формата на описанието на аргументите. За разлика от C, в Go името на променливата е на първо място и едва след това - нейният тип (което е логично и съобразено със системата на човешкото мислене: "променлива от такъв и такъв тип"). Типът връщане на функция в Go трябва да се постави в края, непосредствено след затварящата скоба (което, между другото, също е логично). В същото време, ако функцията трябва да върне няколко стойности (възможно е в Go), техните типове и (по избор) имена трябва да бъдат изброени разделени със запетаи и заобиколени от скоби. Нашата функция няма връщана стойност - след като влезе в отделна нишка, тя така или иначе няма да може да върне нищо. Функцията трябва да повтаря процедурата "sleep-report" броя пъти, посочен в променливата count, така че ред 7 започва цикъл for, чието въвеждане е напълно подобно на неговия аналог в езика C, с изключение на липсата на скоби .

За да изпратим нишката на таймера в режим на заспиване, ние използваме функцията Sleep (ред 8) от предварително импортирания времеви пакет. Аргументът му за продължителност на заспиване трябва да е от тип int64 (подобно на long в C), така че трябва да използваме cast, компилаторът няма да го направи вместо нас (и с право, ние сме по-умни). За да може главната нишка да знае кога ще приключи нишката на таймера и да може да се справи с тази ситуация, таймерът трябва да я предупреди. Следователно, редове от 9 до 15 проверяват дали е достигнат максималният брой повторения на съня. За това се използва стандартният оператор if, който е останал непроменен от времето на C, но, подобно на for, е загубил скобите. Ако това е последното повторение, на екрана се изписва "Изпращане на последното съобщение ...", а съобщението "Стоп!" влиза в канала, в противен случай на екрана се показва "Изпращане на съобщения ...", а каналът отива "Продължи" . Каналите в Go се въвеждат, така че само низ може да бъде изпратен до ch, деклариран като низ chan (Проверката на типа на Go се извършва по време на компилиране, така че грешките са лесни за улавяне). На ред 16 нишката потвърждава, че съобщението е изпратено, като отпечатва низа "Изпратено!" към екрана.

Както в C, в Go индикаторът за стартиране на програмата е основната функция (редове от 20 до 36), в рамките на която ще се изпълнява основната нишка. Всичко, което нашата основна функция трябва да направи, е да създаде нов канал, да го предаде на функцията таймер, да го изпрати в отделна нишка и да изчака резултатите.

За да получавате съобщения от канал, имате нужда от променлива приемник. Тази роля ще се играе от низовата променлива str, декларирана в началото на функцията с помощта на ключовата дума var (стойността й автоматично ще стане нула, което е еквивалентно на NULL в C). За създаване на канал се използва вградената функция make() (ред 23), която просто разпределя памет за посочения тип данни и я инициализира на нула. В допълнение към каналите, можете да създавате асоциативни масиви и срезове с помощта на make; new() се използва за разпределяне на памет. Не можем просто да декларираме променлива от тип chan string и да работим с нея, защото буферът, използван за съхраняване на данните, предавани по канала, няма да бъде разпределен. Обърнете внимание и на имплицитната декларация на променливата ch, която се осъществява с помощта на оператора ":=" (въвеждането е запазено, променливата ще има типа на присвоената стойност). На ред 24 таймерът накрая се изпраща в отделна нишка. И това става с помощта на една-единствена ключова дума – отивам.

Сега, когато таймерът е изпратен да свърши своята работа, нишката на главата може само да чака съобщения. За да получава съобщения от нишка, Go използва описания по-горе оператор "<-", который теперь следует направить "из потока в принимающую переменную":

Но ако добавим само този един ред към кода, тогава основната нишка ще продължи да работи след получаване на първото съобщение и в крайна сметка ще се прекрати, без да обработва останалите съобщения. Така че имаме нужда от безкраен цикъл. Той заема редове от 26 до 35. Go не включва "реално" while, така че ако искате да създадете условен цикъл, просто трябва да поставите условието след ключовата дума for и да не се потите (или не посочвате нищо в всички, както направих и аз).

При всяка итерация на цикъла съобщение, дошло от нишката на таймера, ще бъде записано в променливата str и в зависимост от съдържанието на съобщението ще бъде избрана една или друга опция за по-нататъшни действия. Обърнете внимание, езикът ви позволява лесно да сравнявате низове без никакви допълнителни функции. Освен това можете да вземете резени и копия от тях (по начина на python или ruby) и да изчислите дължината с помощта на ключовата дума len (всичко това важи и за масивите).

За да стартирате програмата, ще ви е необходим компилатор, който може да бъде изтеглен от официалния уебсайт на езика (въпреки че досега са налични само версии за UNIX, Plan9 и MacOS X). Ако не искате да го инсталирате (или имате Windows), можете да стартирате програмата, като използвате специален формуляр на уебсайта golang.org (но поради ограничението на продължителността на програмата, времето за заспиване на нишката на таймера ще трябва да бъде значително намалена). Това е всичко.

Чакай, това не е многонишково, нали?

Да, вероятно сте забелязали, че поради блокиране на канали, дори на многоядрен процесор, само една нишка от нашата програма ще бъде активна едновременно, докато другата ще чака за изпращане/получаване на съобщение. Това е вярно и Go има редица инструменти за справяне с този проблем.

  1. Каналите могат да се проверяват за съобщения. Ако низът " str =<-ch " заменить на " str, ok = <-ch ", то головной поток не будет заблокирован, даже если в канале нет сообщения. Вместо этого в переменную ok будет записано значение false и работа потока продолжится. Естественно, дальше можно поместить проверку на " ok == false " и успеть выполнить какую-то полезную работу, а затем начать новую итерацию цикла и вновь попробовать получить значение. Кстати, таким же образом можно выполнить проверку в потокеотправителе:

добре:=гл<- "Продолжаем"

  1. Каналите в Go могат да бъдат буферирани, тоест да могат да натрупват определен брой съобщения, преди изпращащата страна да бъде блокирана. Всичко, което трябва да направите, е да добавите един допълнителен аргумент към make call:

ch:= make(chan string, 10) // създаване на канал с буфер от 10 позиции

Имайте предвид обаче, че това няма да работи в нашата програма. Докато спя, нишката на таймера няма да може да запълни канала със съобщения наведнъж, тъй като след всяко заспиване контролът все още ще се прехвърля към главната нишка.

  1. Можете да добавите една или повече функции към програмата и да ги изпратите в отделни нишки, тогава те ще работят тихо паралелно и когато таймерът „звъни“ определен брой пъти, всички те ще бъдат унищожени заедно с основната нишка. Ако обаче искаме да получим резултата от тези потоци през канала, тогава отново ще се сблъскаме с ключалки или ще бъдем принудени да направим много проверки за наличие на съобщения в каналите, както е описано в първия параграф. Но това може да се избегне с помощта на "оператора за избор на нишка":

изберете(
случай str =<-ch1:
// обработваме съобщението от първата нишка
случай str =<-ch2:
// обработваме съобщението от втората нишка
случай str =<-ch3:
// обработваме съобщението от третата нишка
}

Програмата ще блокира изявлението за избор, докато се появи съобщение в един от каналите. След това съответният блок ще бъде изпълнен. Така че след обработка на едно съобщение, select again преминава към слушане на канали, то трябва да бъде поставено в безкраен цикъл. В същото време, ако в моментите между пристигането на съобщенията нишката трябва да извърши някаква работа, тогава тя трябва да бъде поставена в блока по подразбиране вътре в избрания.

Инструкцията select се използва много широко в програмирането на Go, с негова помощ е обичайно да се създават "диспечери на съобщения", които разклоняват програмата в много нишки веднага след стартирането и след това влизат в безкраен цикъл и започват да обработват съобщенията, които са дошли от тях. В операционната система Inferno (всички приложения на която са написани в предшественика на Go на Limbo) по този начин е реализиран многопрозоречен графичен интерфейс.

констатации

Go е все още млад, но много обещаващ език, чието създаване взе предвид повече от тридесет години опит в разработването на операционни системи и езици за програмиране (Роб Пайк прекара двадесет години в изследвания в областта на многонишковото програмиране, по време на които са създадени езиците Squeak, NewSqueak и Limbo). Go е продуктивен, удобен за програмисти и красив.

След като овладеете този език, вие ще можете да пишете програми, които ще бъдат много по-ефективни от всичко, написано на традиционни езици за програмиране.

Въпреки че Go е все още много млад език, той вече се използва в много много важни системи в Интернет и неговият обхват ще продължи да расте. Следователно изучаването на Go програмиране е една от най-добрите инвестиции за програмиста в момента. В тази статия ще направим малко въведение в програмирането на Go.

Разбира се, трудно е да обхванете програмирането изцяло в една статия, но ще научите основите, които ще ви помогнат допълнително. Но преди да преминем към разглеждането на езика, нека да поговорим за историята на неговото развитие и структура. Статията е предназначена предимно за тези, които вече знаят какъвто и да е C-подобен език за програмиране, така че материалът може да изглежда сложен за начинаещи, но може да бъде полезен и за тях. Не казвам, че програмирането в Go от нулата е невъзможно, просто за това е необходима по-подробна литература.

Езикът Go е елегантен и прагматичен, но някои от неговите характеристики имат смисъл само в определени исторически контексти. Историята на Go започва с C. В много отношения C се превърна в основата на JavaScript, Ruby, Python, C++, C# и Java. Компилаторите или интерпретаторите на някои от тези езици дори са написани на C. Влиянието на C е лесно да се види на много езици. Разработено е от Денис Ричи за създаване на ядрото на Unix и по-късно е използвано за създаване на ядрото на Linux.

Езикът Go е създаден от легендите на Unix и C ерата. Докато работеха в Google, Робърт Гризмър, Роб Пайк и Кен Томпсън бяха разочаровани от езиците C поради проблемите си. Bjarne Stroustrup, който създаде C++, каза: "C улеснява стрелянето в крака, в C++ е по-трудно, но ако стреляте, ще взривите целия крак."

Go наследява много добри неща от C. Ключовите думи и силата на синтаксиса, процедурния подход са силните страни и на двата езика. От друга страна, ръчното управление на паметта и времето за компилиране е проблем на C. Go решава тези проблеми със събирането на боклука, безопасността на паметта и много бърза компилация.

Java е езикът по избор за много големи компании с големи екипи за разработка. Go използва това предимство от Java и се опитва да бъде страхотен език за големи групи разработчици. Езикът Go няма недостатъците на обектно-ориентираното програмиране като наследяване. Всичко е реализирано с помощта на сбит синтаксис на интерфейса.

Можете също така да откриете определени прилики с динамичните езици, Go приемайки стила на писане на код от Python, възможност за персонализиране от Ruby и прост паралелизъм, зашит в ядрото на езика, като Node.js. Всичко започна като език, който реши някои проблеми на C и се превърна в страхотен език за програмиране с общо предназначение.

Отидете на програмиране

Преди да преминем към примери за писане на програми, бих искал да говоря малко за синтаксиса на езика.

1. Синтаксис на езика Go

Най-важното нещо, което трябва да се каже, е структурата на програмата. Донякъде е подобен на Java и Python. Програмата е разделена на така наречените пакети, които могат да се разглеждат като алтернатива за включване или модули в Python. В допълнение, пакетите ви позволяват да персонализирате обхвати за променливи. Пакетът се импортира в програмата с помощта на оператора за импортиране:

импортиране име на пакета

Всяка програма ще има променливи. Go е силно въведен език, така че всяка променлива трябва да бъде декларирана и въведена, преди да може да се използва:

тип име на променлива

Имената на променливите могат да използват руски език. Но ако незабавно зададете променливата на стойност, тогава самият език ще определи нейния тип:

var име на променлива := стойност

Можете също да създавате указатели. За да направите това, просто добавете звездичка пред името на променливата:

var *тип на_променлива

За достъп до променлива, която е декларирана вътре в пакет от друг пакет, важно е да се отбележи, че само променливите с главни букви са достъпни отвън:

име на пакета. име на променлива
име на пакета. име на функция

Основните инструкции за управление са много сходни по своя синтаксис с тези, познати в C:

ако условие (
действия
}

Цикълът for тук е точно същият като в C, само без скоби, изглежда още по-просто така:

i:= 0; и<= ограничитель; i++ (
действия
}

Функциите Golang се декларират с помощта на директивата func и можете да посочите не само параметри, но и връщане на променливи в нея:

func име на функция (получени променливи) (връщане на променливи){
действия
}

Важно е да се отбележи, че точката и запетаята след редовете не се поставя. Вместо OOP класове, Go използва структури, които могат да имат полета и методи и могат също да имплементират интерфейси. Инструкцията за тип се използва за деклариране на структура:

тип структура_име структура (
име_на_поле_тип_на_поле
}

В допълнение към полета, структурите могат да имат методи, което им позволява да се използват като класове. Декларацията на метода е малко по-различна от функцията golang:

func (име на указател *struct_type ) method_name() (
действия
}

Структурните обекти се създават по същия начин като обикновените променливи и техните полета могат да бъдат достъпни чрез точка:

име_обект . method_name (параметри)

Ние също така се отнасяме към полетата чрез точка:

име_обект . име на полето

Сега знаете основите на езика и е време да се приближите до практиката. След това ще бъде програмиране в Go и Golang примери, минимум теория.

2. Създайте Hello World

Нека напишем първата си програма, както обикновено, тя ще бъде програма, която показва реда "Здравей свят!". Можете да инсталирате Go на вашата система или да използвате онлайн услугата play.golang.org, която ви позволява да стартирате програми директно във вашия браузър. Ще работим с онлайн услуга.

Когато отворите сайта, ще видите готовия код на първата програма:

пакет основен
импортиране ("fmt")

func main() (
fmt.Println("Здравей, детска площадка")
}

Както можете да видите, синтаксисът е почти същият като това, което сме виждали досега. В първия ред показваме, че този файл принадлежи към основния пакет, във втория импортираме пакета fmt, който отговаря за стандартните входни и изходни функции. Тук са необходими скоби, за да импортирате няколко пакета наведнъж, можете просто да добавите имена, разделени със запетаи.

След това се декларира основната функция, която ще се изпълни при стартиране на програмата. Всяка програма Go трябва да съдържа основна функция. В динамичните езици изпълнението на скрипта започва от горната част на файла надолу. В Go изпълнението започва от основната функция, така наречената входна точка.

Вътре в основната функция ние извикаме функцията на библиотеката fmt, която импортирахме по-рано, използвайки синтаксиса на точки. Методът printLn отпечатва низ на екрана.

За езика Go е приет специфичен синтаксис. Дори ако компилаторът няма да хвърля грешки поради несъответствие, най-добре е да се придържате към него. Обичайно е да се използва регистър на камила за имена на променливи, т.е. FooBar или Foobar вместо foo_bar. Също така имайте предвид, че Go не толерира никакви знаци преди отварящата скоба. Дори ако поставите нов ред, ще получите грешка:

Отстъпът също е стандартизиран в Go, въпреки че няма такива изисквания като в Python.

3. Основи на езика Go

Помислете за работа с променливи и структури. Ще бъде полезно за начинаещи потребители. Както казах, езикът е статично въведен. В Python, Ruby или JavaScript трябва да направите много проверка. Go се отървете от този проблем. Например, нека усложним предишния ни пример:

В този пример за изхода отговаря нова функция - print. Тук изрично е посочено, че тя трябва да предаде низ (низ). И в основната функция създаваме променлива от тип низ и я предаваме за печат. Ако предадем нещо друго, получаваме грешка. Ако например промените типа на променлива на int, ще получите това:

не може да използва "Здравей свят!" (тип низ) като тип int в присвояването

Също така ще получите грешка, ако сте декларирали променлива или сте импортирали пакет, но не сте го използвали. Има още много неща, които можете да правите с Go, едно от тях са структури. Нека да усложним нашата програма още повече, да създадем структура на сайта с полета за име и url, които ще описват сайт:

Структурата ще има метод за печат, който отпечатва низа „Добре дошли...“. В основния метод инициализирахме структурата и присвоихме нейните стойностни полета и след това извикахме метода за печат.

Езикът за програмиране Go има още много интересни функции и възможности. И дори не сме се доближили до повечето от тях. Ако искате да се научите да плувате, трябва да скочите във водата. Само чрез практика ще можете да използвате този език свободно.

констатации

Go програмирането може да бъде бъдещето на развитието. Това е красив език, който придоби популярност за сравнително кратък период от време. Надявам се информацията в тази статия да ви е била полезна и сега ще ви бъде по-лесно да овладеете този език.

Хареса ли ви статията? Сподели го
Горна част