Golang (Go) — молодой, но набирающий популярность язык программирования. Его разработали в Google для решения локальных задач, но теперь используют в Uber, Medium, DailyMotion, Twitch и других компаниях. Узнали у разработчиков, почему они выбрали Golang, какие преимущества есть и стоит ли учить его как первый язык. 

«Go — не язык «для всего на свете», Google создал его для решения конкретных задач»


Ильназ Гильязов, сооснователь компании AIMS и автор программы курса «Golang-разработчик с нуля» Нетологии

Почему перешел на Go. Когда мы разворачивали большое количество микросервисов на Java/Kotlin, потребление памяти сильно сказалось на стоимости «железа». Оптимизация затрат заставила искать менее ресурсоемкие альтернативы. Попробовали Go — уменьшили потребление памяти в несколько раз. При этом, от Java/Kotlin не отказываемся, благо можно аккуратно интегрировать все это вместе в рамках микросервисной архитектуры. 

Почему компании переходят на Go с других языков. Go проще множества языков и позволяет даже большим командам создавать поддерживаемый код, не теряя при этом в качестве кодовой базы, — поэтому компании обращают на него внимание. Обычно всё начинается с эксперимента из серии «а не попробовать ли нам этот кусок переписать на Go — говорят, что станет быстрее/производительнее/меньше потреблять железа». Если эксперимент прошел успешно, продолжают внедрять Go, переписывая и другие куски, либо начиная разработку новых сервисов сразу на нем. Обещанная возможность достаточно легко создавать backend, оптимизированный под высокие нагрузки, стимулирует попробовать язык при разработке с нуля. Но нужно понимать, что Go — не язык «для всего на свете», Google создал его для решения конкретных задач.

Какой порог входа в Go и что нужно уметь. Порог входа невысокий, потому что Go создавался для быстрого изучения и применения. В нем нет сложного синтаксиса и множества способов сделать одно и то же.
Если говорить про backend-разработку, то здесь набор знаний более-менее типовой:
сам язык и его инфраструктура: синтаксис, стандартная библиотека, подключение внешних зависимостей;

  • Git;
  • понимание работы frontend (web и mobile) и backend;
  • cетевой стек;
  • SQL или одна из NoSQL баз данных — в зависимости от того, что используют в компании;
  • Linux;
  • авто-тесты, CI/CD;
  • микросервисы;
  • Docker, Kubernetes.

Чем больше знает специалист, тем лучше. Поэтому не лишними будут системы кэширования (например, Redis), Messaging (RabbitMQ, Kafka), логирование и так далее.
Часто компании в своих вакансиях требуют знание Python/PHP/другого языка, а также «опыт либо желание изучить/перейти/писать на Go».

Насколько востребованы и сколько зарабатывают Golang-разработчики. По данным HeadHunter, в России более 1800 вакансий разработчиков на Golang. Средняя зарплата junior-специалиста 80 тысяч рублей. 
Среди работодателей можно увидеть Яндекс, Mail.ru, Рамблер, Авито, Ozon, МТС, Мегафон. Но разработчиков, которые могли бы закрывать эти вакансии, не хватает. 

«Популярность Go растет только по одной причине — нет альтернатив»


Ринат Хабибиев, руководитель проектов в TalentTech

Почему перешел на Go. Работать на Go начал из-за потребности в более производительном решении по сравнению с популярными скриптовыми языками. 
О популярности Go. Go активно используется только по одной причине — нет других альтернатив. Все, что существует на текущий момент, либо менее производительное (PHP, Ruby, Python), либо слишком сложное (C/C++, Rust), либо имеет проблемы с платформой и совместимостью с Linux (Java/Kotlin, Apple Swift).

О сложностях в погружении. Проблем с погружением в Go, как правило, ни у кого не возникает. А так как Go это в основном про веб-разработку, то веб-разработчики входят в него очень быстро. Как вспомогательный инструмент Go очень даже неплох.
Но мне в Go очень не хватает вещей, которыми я активно пользуюсь в других языках программирования и отсутствие которых мешает моей продуктивной работе: отсутствие полноценной поддержки парадигмы ООП и дженериков (generics).

Можно ли стать Golang-разработчиком без опыта. Устроиться разработчиком Go без опыта работы на Go можно. При хорошем знании другого языка освоить Go совсем даже несложно — опытный работодатель это знает. К тому же, часто смотрят не на опыт работы с конкретным инструментом, а на совокупный опыт работы в отрасли.

«Go быстро развивается, многие детские болячки уже решены»


Александр Типугин, старший разработчик компании PIRL Ventures

Почему начал работать на Go. Повод попробовать Go был как раз на стыке личного интереса к языку и потребностей компании. Тогда возник новый проект, связанный с внутренней инфраструктурой, и основными требованиями к нему были высокая производительность, многопоточность и удобство написания сетевого кода. Ruby и PHP, которые на тот момент были основными инструментами в компании, в эти требования не очень вписывались. Поскольку на тот момент я как раз начал посматривать в сторону Go, было решено попробовать его.

О популярности Go. Думаю, большую роль сыграла мода на микросервисы. Тащить в небольшие узкоспециализированные сервисы здоровенные фреймворки из мира монолитов не имело смысла, и все стали обращать внимание на Go. Популярность Kubernetes, Docker и других крупных проектов на Go также помогают языку в этом деле. Go быстро развивается, многие детские болячки уже решены, либо вот-вот решатся во второй версии.

О сложностях в погружении. Go достаточно простой язык. Минимум языковых конструкций, всего 25 ключевых слов. Не нужно управлять памятью (есть GC) и потоками (есть планировщик). Чтобы сесть и понять с нуля, что происходит в коде, надо не так уж много времени. Другое дело, что многие вещи по началу кажутся довольно странными, некоторые концепции (каналы, горутины) могут быть не сразу понятны и очевидны.

Можно ли стать Golang-разработчиком без опыта. Многие компании сейчас активно ищут людей с любым бэкграундом в плане языков, если те готовы выучить Go и перейти на него. Некоторые знакомые разработчики примерно так и перешли на Go.

«Go — простой, но очень мощный язык с отличной документацией и хорошо продуманными встроенными инструментами»


Данил Наумов, Backend разработчик QIWI Blockchain Technologies

Почему начал работать на Go. Я начал писать на Go из-за потребностей компании. Мы реализовывали проект, в котором была выбрана микросервисная архитектура. Go отлично подходил для наших целей.

О популярности Go. Go — простой, но очень мощный язык с отличной документацией и хорошо продуманными встроенными инструментами.
Язык создан компанией Google в качестве альтернативы C++ и Java для разработчиков приложений в контексте задач компании. Так как Google нуждается в большом количестве разработчиков, язык должен быть достаточно простым, с низким порогом вхождения, но при этом быстрым, с максимально удобной инфраструктурой. Это во многом определило бурный рост и внедрение этого языка за пределами Google.

О сложностях в погружении. Нет, так как у Go очень подробная документация, а также много хороших книг, статей, огромное количество мануалов и большое комьюнити.
Стоит ли учить Go как первый язык. На мой взгляд, да. Это достаточно низкоуровневый, но при этом простой в освоении язык, который позволит понять принципы работы памяти, многопоточности, синхронизации процессов.
Можно ли стать Golang-разработчиком без опыта. Без опыта найти работу довольно сложно. Но при этом, учитывая все возрастающую потребность в разработчиках на Go, мне кажется, что знание этого языка будет большим преимуществом.

От редакции


Go — простой и удобный язык, не перегруженный сложными конструкциями, который подходит для быстрого изучения. С его помощью создаются приложения в самых востребованных сферах. Спрос на Golang-разработчиков растет, а специалистов не хватает.
На курсе «Golang-разработчик с нуля» учим разрабатывать микросервисы и полноценные приложения — студенты создают с нуля приложение для организации корпоративной соцсети и осваивают востребованную профессию.

Комментарии (59)


  1. Zet_Roy
    16.10.2019 19:08
    +2

    Golang (Go) — молодой, но набирающий популярность язык программирования.

    Появился в 10 ноября 2009.
    Не такой уж и молодой и его популярность давно ушла.


    1. sT331h0rs3
      16.10.2019 20:15
      +4

      Если его популярность давно ушла, то что же пришло ему на смену?


      1. fougasse
        17.10.2019 00:58
        +2

        А он когда-то лидировал, чтобы его смену искать?


      1. VIkrom
        17.10.2019 09:52

        Правильнее будет сказать, что хайп прошел. Когда бросались переписывать на Го, чтобы как все ну и Гугл же.


  1. PsyHaSTe
    16.10.2019 19:13
    +7

    Все, что существует на текущий момент, либо менее производительное (PHP, Ruby, Python), либо слишком сложное (C/C++, Rust), либо имеет проблемы с платформой и совместимостью с Linux (Java/Kotlin, Apple Swift).

    Простите, а какие проблемы с совместимостью с Linux у Java?


    Тащить в небольшие узкоспециализированные сервисы здоровенные фреймворки из мира монолитов не имело смысла, и все стали обращать внимание на Go.

    А фреймворки из мира монолитов это что? Ну если не считать спринг, а взять какой-нибудь дотнет. Минимальной толщины ASP.Net Core, который просто занимается роутингом запросов? Нужен. ОРМ чтобы руками не маппить структуры на монги/постгресы? Дайте два. Работа с отказоустойчивостью из коробки (тот же Polly) не нужен? Да вроде нужен.


    Но ничто из этого не монструозно, комбинируется в любых количествах как нужно, а жить без этого и писать SQL руками не очень. Да, я видел gorm, он ужасен. Особенно та часть, где нельзя сделать фильтр по дефолтному значению класса. То есть буквально Where(x => x == 0) не сделать. Это конечно обходится, но какой ценой. Про более сложные фильтры молчу, нужно изучать спецификацию конкретного орм, и строчками писать все тот же SQL. С таким подходом от ОРМ больше проблем, чем толку, соглашусь. Только это свойство не всех ОРМ вообще, а только данных.


    Go достаточно простой язык.

    На мой взгляд — слишком простой. В итоге 3party-библиотеку качественную просто физически невозможно написать. Остается только надеяться на милость std, что в очередной версии туда добавят то, что вам нужно. Наверное, с идеологией "всё своё, что не подходит — выкинем и перепишем" это не проблема, но у меня почему-то полное отторжение вызывает.


    1. QtRoS
      16.10.2019 20:01
      -1

      C# хорош, и все могло сложиться совершенно иначе, если бы фишки .net core завезли году так 2010-2012. Но историю переписать нельзя, поэтому Go занял нишу микросервисов и консольных утилит, в блокчейне преуспел, да и в целом имеет более высокий уровень хайпа. Роб Пайк все давно уже все про него рассказал — в языке простые ортогональные фичи. Идеально подходит для тех, кто устал от сложности современного ООП (который, как известно, задумывался не таким), от всяких мракобесий вроде дефолтной реализации в интерфейсе и так далее. Эдакий С на стероидах.


      1. evocatus
        17.10.2019 01:39
        +1

        Не C, а Pascal на стероидах. Потому что у Pascal и Go — сильная типизация, процедурное программирование (да, то, что в Go вместо ООП, было описано уже в книге Энтони Хоара «Structured programming», там процедуры со структурами были связанные и пр., а гошные каналы (сиречь CSP) придумал Эдсгер Дейкстра примерно тогда же).
        А вот за ad-hoc полиморфизм — жирный минус. Я не понимаю как такие великие (без всякой иронии) люди как Пайк, Гризмер и Керниган не увидели, что нужно делать либо динамическую типизацию, либо обобщённое программирование.

        Простая задача: нужно написать полиморфную функцию, которая могла бы принимать на вход любую структуру, у которой есть поле ID типа int. (если кому-то подумалось, что это структура для отображения таблицы из базы, а ID — суррогатный ключ, то так и есть). В Go это НЕВОЗМОЖНО. Реализовать такое поведение можно, но это всё будут уродские способы.
        1) Реализовать для каждого такого типа getter и setter методы для этого поля, создать интерфейс, состоящий из этих методов и передавать в полиморфную функцию интерфейс. Ужасающий копипаст и потенциальная сложность O(n) при изменении кода.
        2) Принимать в полиморфной функции interface{} и использовать рефлексию. Которая расползётся как рак по всему коду и по праву считается в сообществе Go антипаттерном (хотя буквально все используют библиотеки, состоящие из использования reflect чуть более, чем полностью — для парсинга JSON, форм HTML, ответов из БД)
        3) Принимать interface{} в полиморфной функции и написать развесистый switch, в каждой ветке которого пытаться кастануть interface{} в конкретный тип (опять же вернуть типизированное значение такая ф-ция не сможет, как и вариант с рефлексией, только вызвать другую функцию, а функций этих должно быть столько же, сколько типов и они должны быть написаны ручками). Это буквально пример из учебника как не надо проектировать программы и делать полиморфизм. Дядюшка Боб за такое откручивает головы.

        Итого мы имеем Pascal с CSP, где вместо нормальных указателей (которые небезопасны, но хотя бы удобны по сравнению с Go) мы притворяемся, что ad-hoc полиморфизм это нормально и современно, а все, кто считает, что код должен быть гибким к изменениям, нужно соблюдать DRY, стремиться к single source of truth и избегать ситуаций, когда изменения в коде имеют сложность больше O(1), просто ничего не понимают в «простоте».


        1. serge-phi
          17.10.2019 07:02

          4) Использовать внедрение структур: play.golang.org/p/uryETmVGJ6D


          1. evocatus
            17.10.2019 15:31
            +1

            Примерно так «наследование» делали в старые времена на Си. Нет, спасибо, я слишком много общался с сетевым стеком Linux и его «полиморфными» структурами.

            А теперь представьте, что я согласен с Кристофером Дейтом и Джошом Беркусом (из PostgreSQL) и являюсь противником суррогатных ключей и хочу сделать полиморфные функции Create, Read, Update, Delete, все из которых принимают параметр — ключ, а он состоит из произвольного количества произвольных типов. Как в таком случае быть?


            1. serge-phi
              17.10.2019 17:40
              -1

              Через интерфейсы.

              play.golang.org/p/tECObTloC3N


        1. QtRoS
          17.10.2019 08:57

          В материалах по Go трудно найти упоминания Pascal, а вот С встречается повсеместно. Более того, и компилятор, и прочие инструменты тоже сначала были написаны на С. И авторы языка сами по себе поклонники языка С. Так что я уверенно могу сказать, влияние и похожесть на этот язык много больше, чем pascal. Утверждение про csp не понял, зачем приведено, его ни в С, ни в Pascal нет. Я не знаток второго, но вроде это одного поля ягоды, во многом схожие языки. Буду признателен, если подчеркнете действительные отличия.


          По поводу второй части — сам пример выглядит не очень показательным для минусов языка, можно найти и похуже что-то, но давайте обсудим тем не менее :) Я правильно понимаю, что в С, С++, С#, Java это тоже нереализуемо? Именно поле, свойство в С# не считается. Насколько я помню в них нет никаких контрактов на наличие поля в любой структуре.


          1. mayorovp
            17.10.2019 10:31
            +1

            А чего это свойство вдруг не считается-то?


            1. QtRoS
              17.10.2019 11:20

              Там написано "поле". "Поле" != "Свойство", вот такая простая логика. В чём тогда вызов? Ну да, синтаксически они выглядят одинаково, но на уровне реализации это совсем иная сущность. Плюс свойство может быть частью интерфейса, тогда задача тривиальна, но интерфейс опять-таки надо реализовать.
              Хотя не исключаю, что задачу в своей интерпретации я излишне усложнил.


              1. mayorovp
                17.10.2019 12:12

                Семантика что у поля, что у свойства — одна и та же, отличаются лишь детали реализации.


                1. QtRoS
                  17.10.2019 12:59

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


                  1. mayorovp
                    17.10.2019 13:21
                    -1

                    "Синтаксический сахар над вызовом специальных функций" — это и есть деталь реализации. Точно так же, как статическое выделение места в объекте является реализацией поля.


                    А семантика у них общая — в обоих случаях это некоторая переменная, привязанная к объекту/структуре.


                    1. QtRoS
                      17.10.2019 13:36
                      -1

                      В C# свойство привязано к переменной только в простейшем случае, а потенциально за ним может быть сколь угодно сложный код. Ввиду этого семантика разная.


                      1. mayorovp
                        17.10.2019 13:40

                        "Сколь угодно сложный код", спрятанный в свойстве — это архитектурная ошибка. Именно по той причине, что у свойства семантика поля.


                        1. QtRoS
                          17.10.2019 13:58

                          Я, собственно, и не говорю, что это best practice, однако такое возможно в реальном коде, соответственно при чтении лучше различать семантику. Взять даже тривиальный пример реализации Singleton с помощью Lazy<> — фактически в момент вызова Value происходит некоторая магия, включающая в себя защиту от двойной инициализации в многопоточной среде, ещё какие-то нюансы. С доступом к полю разница весомая.
                          P.S. Семантика в смысле некоторой смысловой нагрузки. При абсолютном синтаксическом сходстве смысловая нагрузка другая. Мы ведь это обсуждаем? :)


                          1. mayorovp
                            17.10.2019 14:45

                            Да, именно так, семантика в смысле смысловой нагрузки.


                            Взять даже тривиальный пример реализации Singleton с помощью Lazy<> — фактически в момент вызова Value происходит некоторая магия...

                            … о которой вызывающему коду знать не обязательно. Вот совсем-совсем необязательно.


                  1. PsyHaSTe
                    17.10.2019 13:31

                    Только вот с этим сахаром работать удобно, а писать то же самое руками — неудобно. В джаве можно обойтись декораторами @Getter, в С++ есть шаблоны в которых это поле можно получить, в сишарпе есть {get;}, а в го что?


                    Мы же не аскетичным программированием занимаемся, чтобы себя ограничивать. Язык дает возможность — мы ей пользуемся. По-поводу "нечестно" — для выбора инструмента нет никакого понятия честности, есть понятие целесообразности и удобности. А то это как сравнивать Си с джавой, но запретить в последней пользоваться ООП "ведь в си его нет".


                    1. QtRoS
                      17.10.2019 13:46

                      Этот тред был про более узкую тему, а именно полиморфную функцию, принимающую любую структуру с полем ID. Пока решения не было в мейнстрим языках.
                      Касаемо Вашего замечания — в Go прямой доступ к полям, примерно как в Python, а-ля we are all adults here :)


                      1. PsyHaSTe
                        17.10.2019 14:03

                        Этот тред был про более узкую тему, а именно полиморфную функцию, принимающую любую структуру с полем ID. Пока решения не было в мейнстрим языках.

                        Все верно


                        void Foo<T: IHasId>(T x) {
                        
                        }

                        Что в C#, что в Java, что в плюсах (там констрейинт правда не повесить вроде, но ошибка компиляции это почти то же в данном случае).


                        1. QtRoS
                          17.10.2019 15:54

                          А чем вариант с интерфейсом Go в данном случае проигрывает? Так же будет функция, которая принимает IHasID, неявно реализованный.


                          1. mayorovp
                            17.10.2019 16:56

                            А почему "неявно"? Насколько я знаю, поле в интерфейс включить нельзя, а метод придётся самому писать.


                          1. PsyHaSTe
                            17.10.2019 18:09

                            То, что в сишарпе я напишу


                            class MyBar : IHasId {
                                public int Id { get; set } = 547;
                            }

                            И всё само будет работать. А вариант без интерфейса выглядит так:


                            class MyBar {
                                public int Id { get; set } = 547;
                            }

                            В данном случае сделать такой интерфейс нам практически бесплатно. Писать явно пары методов и прокидывать их в интерфейс не очень хочется. Мелочь, но если умножить на количество сущностей в коде оказывается очень прилично. У меня лично в текущем небольшом микросевриса 60 сущностей наследуемых от


                            interface IEntity { 
                               Guid Id { get; } 
                            }


                            1. QtRoS
                              17.10.2019 19:18

                              Т.е. вопрос свелся к тому, что свойства в C# удобнее пары метода? Ну на эту тему даже с Java можно похоливарить, не обязательно с Go :)


                              1. PsyHaSTe
                                17.10.2019 20:37
                                -1

                                Да че тут холиварить, в джаве:


                                public class MyBar implements IHasId {
                                  @Getter @Setter private int id = 547;
                                }


                                1. QtRoS
                                  17.10.2019 23:12
                                  -1

                                  Ну да, давайте еще скажем, что в JavaScript есть каррирование, только потому что можно форк Babel сделать (по мотивам недавней статьи на Хабре) и там реализовать. Все, что не язык из коробки, не имеет смысла приводить в пример. Для Go тоже есть свои форки с наработками дженериков, но никто не говорит, что они есть в языке.


          1. evocatus
            17.10.2019 15:42
            -2

            В С это можно сделать и способы будут как раз похожи на описанные мною варианты (потому что interface{} — это по сути void *). Вдобавок есть довольно известный способ, когда создаются структуры, у которых первые n полей идут в одном порядке и имеют одинаковый тип (аналогично тому, что подсказал выше serge-phi ). Но на C никто веб-сервисы не пишет, правда удивительно?

            В Java, C++, C# это реализуемо, притом элегантно, гибко и удобно.

            Насчёт происхождения Go рекомендую посмотреть книгу «Язык программирования Go» Донована и Кернигана, где на 13-й странице показано, что Go происходит также от Pascal и Oberon. И ещё раз повторю: Go изначально задумывался строго типизированным — это настолько радикально отличает его от С, что я даже не знаю что тут ещё добавить.


            1. QtRoS
              17.10.2019 15:52

              Покажите пример на C#, так можем предметно его обсудить.


              1. evocatus
                18.10.2019 00:11

                	interface IModel<Key, Data>
                	{
                		Key Insert(Data data);
                		void Update(Key key, Data data);
                		void Delete(Key key);
                		Data Select(Key key);
                	}
                


                1. QtRoS
                  18.10.2019 00:22

                  Это точно решение первоначальной постановки?

                  нужно написать полиморфную функцию, которая могла бы принимать на вход любую структуру, у которой есть поле ID типа int

                  Ни полиморфной функции, ни поля ID типа int не вижу)


                  1. evocatus
                    18.10.2019 00:26

                    Это лучше, это решение более общего случая, который я раскрыл чуть ниже того комментария.
                    Полиморфная функция должна принимать на вход этот интерфейс. А при его реализации в случае с ID типа int нужно будет просто дать соотв. тип вместо Key.

                    P.S. Первый раз в жизни пишу на С#


                    1. QtRoS
                      18.10.2019 00:47

                      Вот бы сейчас рассуждать про язык, на котором никогда не писал :)
                      Не обижайтесь, но это выглядит странно. Сначала ставите пусть и вырожденную, но вполне конкретную задачу, утверждаете о ее реализуемости, а затем приводите что-то совсем иное, и как оказывается на языке без практического опыта. Немного не то, что я ожидал.


                    1. PsyHaSTe
                      18.10.2019 12:23


            1. mayorovp
              17.10.2019 16:58

              Ну нет, interface{} — это всё же не void*. Звезду Пустоты можно куда угодно скастовать, и если программист ошибся — то будет UB, в то время как в Go при неверном касте interface{} будет всего лишь паника.


        1. pawlo16
          17.10.2019 20:51
          +1

          Пример про ID высосан из пальца. Достаточно передать в функцию сам ID в виде инта или указателя на инт. Надумали проблему и абсурдные решения. Отлично проводите время!

          Ни какого «неудобства» в указателях go нет. Это ваша субъективная оценка, не надо её навязывать.


          1. PsyHaSTe
            17.10.2019 20:59

            Отлично. Теперь кто-то ошибся, и передал сущность с id == 12, а качестве второго интового аргумента передал 10. Что в этом случае делать?


            1. pawlo16
              18.10.2019 16:37

              Ответ очевиден. Предать в функцию DTO с явным указанием типа. Объяснить автору кода его не правоту — непонимание смысла статической типизации в Go. Мотивировать исправиться.


    1. anton19286
      17.10.2019 12:24
      +1

      Не понял последний абзац. Стандартную библиотеку пишут люди, преимущественно на Го. Почему для других это невозможно?


      1. PsyHaSTe
        17.10.2019 13:19

        Ну например в Go1 есть генерики, но только для std. Никогда не замечали, что массив или мапа это генерик? Что функция append буквально объявлена как генерик func append(s []T, vs ...T) []T?


        Но нет, сами вы не сможете написать такую функцию, вы же всего лишь разработчик, а не богоподобный член кор тимы Go.


        1. serge-phi
          17.10.2019 15:25

          А при чем тут библиотека? map, array, slice, channel — это встроенные типы (как int, string и т.д), append/make/new — это встроенные функции, а не библиотечные.


          1. mayorovp
            17.10.2019 15:31
            +2

            Ну, реализация append вполне себе библиотечная функция, только называется она growslice


            Собственно, об этом и было написано в последнем абзаце: разработчики стандартной библиотеки могут попросить разработчиков компилятора добавить новую встроенную функцию (если это вообще разные разработчики), а разработчикам сторонней библиотеки такая возможность недоступна.


            1. serge-phi
              17.10.2019 15:50

              Нет, не могут. Каждое изменение языка (а добавление новой встроенной функции это и есть изменение языка) проходит длительный цикл обсуждения.


              1. mayorovp
                17.10.2019 16:55

                Значит, могут после длительного цикла обсуждения.


        1. TargetSan
          17.10.2019 16:59
          -1

          Долго ждал момента чтобы написать :)
          По хорошему это никакие не дженерики, а интринсики — т.е. подобные функциям встроенные средства компилятора. Нет в Go дженериков, что бы ни писали по этому поводу его пропоненты.


          1. PsyHaSTe
            17.10.2019 18:11

            Окей, как скажете.


            Тогда ответьте на вопрос, если мне нужно написать свой append, а встроенный интринсик по какой-то причине не подошел (например, я хочу добавлять элемент дважды), то как мне поступить? Или это "ненужно" и я делаю задачу не go way?


            1. TargetSan
              17.10.2019 20:47

              Вы неверно поняли мой комментарий. Я нигде не говорил, что дженериков нет и не надо. Я сказал как раз, что никаких дженериков там нет несмотря на все рассказы евангелистов про тот самый append. Это не более дженерик чем методы массивов в Java до 1.5. И да, они нужны чёрт побери.
              Отвечая же на ваш вопрос — никак, без адских костылей как по приведённой ссылке growslice.


              1. PsyHaSTe
                17.10.2019 21:00

                Вы неверно поняли мой комментарий. Я нигде не говорил, что дженериков нет и не надо. Я сказал как раз, что никаких дженериков там нет несмотря на все рассказы евангелистов про тот самый append.

                Если что-то выглядит как утка и ходит как утка, то наверное это утка.


  1. darkit
    16.10.2019 23:30
    +1

    После Джавы единственное что нравится в Го это что на выходе один бинарник.
    Все остальное оставляет впечатление сырого продукта.

    Куда класть исходники, как организовывать пакеты? Кто в лес кто по дрова, в Джаве открываешь мавен проект и в принципе все понятно как собирать куда смотреть.
    Принцип что пакет это нечто большое и внутри куча файлов прокатит для чего то мелкого, но как делать ентерпрайз на нем и легко бегать между файлами хз.

    Чем собирать проект? Так же, кто make, кто свое что то пишет, кто просто go ... и поехали, можно еще взять Bazel. и тогда начинается веселье, сделали go get ... потом не забыли натравить bazel gazelle ... который легко затирает модифицированные правила или bazel test не видит пользовательский aws конфиг или… все вообщем как то решаемо но хочется то легкости.

    Решили тестировать, давайте моки подключим. В древней Джаве @Mock и поехали. В модном Го — сперва mockery -dir internal/cache -name PersonCache, который генерирует мок и кладет в файлик и только потом давайте его использовать. Добавили метод в исходный объект, поехали перегенерировать мок :)

    И можно еще вспоминать кучу подобных вещей. Я бы не сказал, что Го простой и легкий язык. Что то быстро на коленки свалять и запустить, то да. Но я такое же быстро на Сприг Буте соберу. А если хочется скорости и памяти поменьше, то надо брать Rust.


    1. excentro
      17.10.2019 08:58
      -1

      Для сборки java в бинарник уже есть graalvm, с появлением которого Go потерял единственное более-менее значимое преимущество перед java.


    1. pawlo16
      17.10.2019 22:22
      +1

      «Куда класть исходники, как организовывать пакеты?»- смотреть в гугол: golang standards project layout

      «Bazel» — это какая-то аберрация. Все проекты Go собираются командой go build с параметрами и тэгами. Или вы что-то делаете не так

      «В модном Го — сперва mockery -dir» — и в чём проблема-то? Если «добавили метод в исходный объект», то всё равно тесты придётся переписывать. Чтобы меньше возится с тестами, используйте тестовые таблицы вместо моков


      1. darkit
        17.10.2019 23:33
        -2

        смотреть в гугол: golang standards project layout

        в джава такого вопроса даже не возникает.

        Все проекты Go собираются командой go build с параметрами и тэгами. Или вы что-то делаете не так

        go build вы соберете какой либо один бинарник. А как быть когда надо прогнать тесты, потом интеграционные тесты, собрать пару бинарников да еще под разные платформы, все упаковать с нужными конфигами и тд, то что вы делаете? Да так чтобы еще все собиралось без танцев на разных машинах у разработчиков и в Дженкинсе.

        и в чём проблема-то?
        — проблема в дополнительном телодвижение. Или как мне сделать spy?

        Чтобы меньше возится с тестами, используйте тестовые таблицы вместо моков
        как тестовые таблицы отменяют моки?
        Вот для примера сравните как делается в Джаве: junit.org/junit5/docs/current/user-guide/#writing-tests-parameterized-tests
        нет никакого кода не нужно для теста, а именно:
        for _, tt := range fibTests {
        actual := Fib(tt.n)


        Те мой коментарий был не о том какой Го плохой, а о том что он сырой еще. И на разработку времени тратится больше без какого либо видного профита на выходе.


  1. dikkini
    17.10.2019 02:03
    +1

    Никому не показалось, что если в статье сделать Ctrl+R: Go/Python то ничего принципиально не изменится?


  1. nehaev
    17.10.2019 18:45

    Попробовали Go — уменьшили потребление памяти в несколько раз.

    Хм… А есть ли какие-нибудь опубликованные бенчмарки Java vs Go? Про GC в Go, например, пишут, что короткие паузы достигаются ценой большего расхода CPU при сборке и большего футпринта в памяти.


    1. serge-phi
      17.10.2019 19:31
      +1

      benchmarksgame-team.pages.debian.net/benchmarksgame/fastest/go.html

      Меньшее потребление памяти и более высокая скорость достигаются за счет того, что Go умеет держать объекты на стеке. Но Java (и С#) выигрывает в сценариях, когда выживает много молодых объектов (это хорошо иллюстрирует тест binary-trees).


    1. EjikVTumane
      17.10.2019 20:39

      Тут тоже тесты, на которые может быть любопытно взглянуть:
      www.techempower.com/benchmarks/#section=data-r16&hw=ph&test=json


  1. Vlad800
    18.10.2019 15:05

    Преимущества Go с технической стороны совсем незначительны по сравнению с его мощной поддержкой от вендора. Здесь чисто внешняя экономика.