Go 1.11 был запущен 24 августа 2018 года. Он представляет несколько действительно необходимых инструментов и компонентов, таких как модули с поддержкой версий, поддержка WebAssembly и улучшения отладки. Он также вносит некоторые изменения в основные пакеты и производительность / время выполнения.

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

Посмотрим, что нового.

Модули

Go 1.11 включает экспериментальную поддержку модулей Go, включая новую команду go get, поддерживающую модули.

Самый быстрый способ воспользоваться преимуществами поддержки нового модуля - это извлечь свой репозиторий в каталог снаружи, создать файл go.mod и запустить команды Go из этого файлового дерева.

Давайте продемонстрируем это. Я использую мощные и стандартные библиотеки тестирования Go.

Давайте клонируем репозиторий для свидетельских показаний в мою любимую папку ~/proj/github.

$ git clone https://github.com/stretchr/testify ~/proj/github/testify
$ cd ~/proj/github/testify

Теперь, чтобы использовать команды Go отсюда, вам необходимо инициализировать это репо как модуль с помощью следующей команды:

go mod init github.com/stretchr/testify

Где github.com/stretchr/testify - это место, где вы обычно помещаете это репо в папке Go src.

Эта команда создаст файл go.mod в корне папки. В проекте, уже использующем существующий инструмент управления зависимостями, такой как godep, glide или dep, go mod init также добавит операторы require, соответствующие существующей конфигурации.

Теперь, если вы откроете файл go.mod, вы увидите список зависимостей с именем модуля.

$ vi go.mod
module github.com/stretchr/testify
require (
    github.com/davecgh/go-spew v1.1.0
    github.com/pmezard/go-difflib v1.0.0
    github.com/stretchr/objx v0.1.0
)

Как вы заметили, эти три являются зависимостями свидетелей. Это Gopkg.toml файл свидетельских показаний:

[prune]
 unused-packages = true
 non-go = true
 go-tests = true
[[constraint]]
 name = “github.com/davecgh/go-spew”
 version = “~1.1.0”
[[constraint]]
 name = “github.com/pmezard/go-difflib”
 version = “~1.0.0”
[[constraint]]
 name = “github.com/stretchr/objx”
 version = “~0.1.0”

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

╭─ ~/proj/github/testify  ‹master*› 
╰─$ go build                               
go: finding github.com/davecgh/go-spew v1.1.0
go: finding github.com/pmezard/go-difflib v1.0.0
go: finding github.com/stretchr/objx v0.1.0
go: downloading github.com/davecgh/go-spew v1.1.0
go: downloading github.com/pmezard/go-difflib v1.0.0
go: downloading github.com/stretchr/objx v0.1.0
╭─ ~/proj/github/testify  ‹master*› 
╰─$ go test 
PASS
ok   github.com/stretchr/testify 0.001s

Таким образом, с Go 1.11 и модулями вы можете писать свои модули Go где угодно, и вам не нужно поддерживать копию в конкретном подкаталоге вашего $GOPATH.

WebAssembly

Go 1.11 добавляет экспериментальный порт в WebAssembly.

WebAssembly (сокращенно Wasm) - это двоичный формат инструкций для виртуальной машины на основе стека. Wasm разработан как переносимая цель для компиляции языков высокого уровня, таких как C / C ++ / Rust, что позволяет развертывать в Интернете клиентские и серверные приложения.

Теперь мы можем запускать Go в браузере, и наоборот - мы можем легко запускать JavaScript в Go. Хотя эта функция находится в экспериментальном состоянии, она по-прежнему довольно полезна.

Этот небольшой пример вызывает Go из Интернета:

wasm-exec.html

<!doctype html>
<!--
Copyright 2018 The Go Authors. All rights reserved.
Use of this source code is governed by a BSD-style
license that can be found in the LICENSE file.
-->
<html>
<head>
    <meta charset="utf-8">
    <title>Go wasm</title>
</head>
<body>
    <script src="wasm_exec.js"></script>
    <script>
        if (!WebAssembly.instantiateStreaming) { // polyfill
            WebAssembly.instantiateStreaming = async (resp, importObject) => {
                const source = await (await resp).arrayBuffer();
                return await WebAssembly.instantiate(source, importObject);
            };
        }
        const go = new Go();
        let mod, inst;
        WebAssembly.instantiateStreaming(fetch("test.wasm"), go.importObject).then((result) => {
            mod = result.module;
            inst = result.instance;
            document.getElementById("runButton").disabled = false;
        });
        let printMessage // Our reference to the Go callback
        let printMessageReceived // Our promise
        let resolvePrintMessageReceived // Our promise resolver
        function setPrintMessage(callback) {
          printMessage = callback
          resolvePrintMessageReceived()
        }
        async function run() {
          console.clear()
          // Create the Promise and store its resolve function
          printMessageReceived = new Promise(resolve => {
            resolvePrintMessageReceived = resolve
          })
          const run = go.run(inst) // Start the wasm binary
          await printMessageReceived // Wait for the callback reception
          printMessage('Hello Wasm!') // Invoke the callback
          await run // Wait for the binary to terminate
          inst = await WebAssembly.instantiate(mod, go.importObject) // reset instance
        }
    </script>
<button onClick="run();" id="runButton" disabled>Run</button>
</body>
</html>

go-call.go

package main
import (
  "fmt"
  "syscall/js"
)
var done = make(chan struct{})
func main() {
  callback := js.NewCallback(printMessage)
  defer callback.Release() // To defer the callback releasing is a good practice
  setPrintMessage := js.Global().Get("setPrintMessage")
  setPrintMessage.Invoke(callback)
  <-done
}
func printMessage(args []js.Value) {
  message := args[0].String()
  fmt.Println(message)
  done <- struct{}{} // Notify printMessage has been called
}

Вы можете найти больше примеров здесь. А вот видео о построении калькулятора с помощью WebAssembly.

Другие изменения, которые следует учитывать

  • Поскольку поддержка модуля Go придает особое значение символу @ в операциях командной строки, команда go теперь запрещает использование путей импорта, содержащих символы @.
  • С помощью нового пакета runtime/trace API аннотаций пользователей пользователи могут записывать информацию на уровне приложения в трассировки выполнения и создавать группы связанных горутин. Команда go tool trace визуализирует эту информацию в представлении трассировки и на странице анализа новой задачи / области пользователя.
  • Среда выполнения теперь использует макет разреженной кучи, поэтому больше нет ограничения на размер кучи Go (ранее ограничение составляло 512 ГБ). Это также устраняет редкие сбои «конфликта адресного пространства» в смешанных двоичных файлах Go / C или двоичных файлах, скомпилированных с -race.
  • Time: теперь поддерживается анализ часовых поясов, обозначенных знаком и смещением. В предыдущих версиях числовые имена часовых поясов (например, +03) не считались допустимыми, и при ожидании имени часового пояса принимались только трехбуквенные сокращения (например, MST).
  • Текст / сканер: метод Scanner.Scan теперь возвращает токен RawString вместо String для необработанных строковых литералов.
  • Есть изменения в криптографии, кодировке, net / http, os, runtime, sync, mime и некоторых других, о которых вы можете прочитать здесь.

Если вам понравилась эта статья, избавьте меня от хлопков - для писателя она означает мир. Следуйте за мной, если хотите прочитать больше статей о Go, JavaScript, технологиях и стартапах.