A few notable changes in Go 1.5

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

At the opening of GopherCon2015, Google go team finally released the Go 1.5beta1 version of the installation package. In the Go 1.5BETA1 release notes, go team also honestly admits that go 1.5 will break a release cycle for the previous 6 months, because go 1.5 changes too much and takes more time to prepare for this release (fix Bug, Write doc). As for the changes to go 1.5, the Go Team staff has been exposed to a number of slide in various Golang technology conferences, including:

-Compiler and runtime changed from C to go (and a few assembly language) rewrite, implement go self Bootstrap (bootstrap)
-Garbage collector optimized to significantly reduce GC latency (Stop the world), enabling GC to run in parallel with other user goroutine in a separate goroutine.
-Standard library changes and introduction of some go tools.

Every change will make gopher excited. But before it was just excitement, this time beta1 out, we can actually experience the "pleasure" brought about by these changes. Go 1.5beta1 's release document is not complete at present, some places also have "to add" the word, May and final go 1.5 release at the time of the version has some difference, but the general content should be fixed. This article would like to share with you the simple experience of what go 1.5 has brought to the Gophers.

One, language

"Map literal"

Go 1.5 is still compatible with Go 1 language specification, but fixed a previous "minor negligence".

In Go 1.4 and previous versions, we can only write code like this:

Testmapliteral.go
Package Main

Import (
"FMT"
)

Type point struct {
x int
y int
}

Func Main () {
var sl = []point{{3, 4}, {5, 6}}
var m = map[point]string{
point{3,4}: "Foo1",
point{5,6}: "Foo2",
}
Fmt. PRINTLN (SL)
Fmt. Println (M)
}

As you can see, for a struct of point, when initializing a slice, there is no need to explicitly take the element type point in slice value literal, i.e.

var sl = []point{{3, 4}, {5, 6}}

Instead of

var sl = []point{point{3, 4}, point{5, 6}}

However, when a point is a key type of the map type, the map is initialized with an explicit element type of a. Go team admits it was an oversight and fix the problem in Go 1.5 this time. In other words, the following code can be successfully compiled in Go 1.5:

Func Main () {
var sl = []point{{3, 4}, {5, 6}}
var m = map[point]string{
{3,4}: "Foo1",
{5,6}: "Foo2",
}
Fmt. PRINTLN (SL)
Fmt. Println (M)
}

"Gomaxprocs"

As Russ Cox's opening keynote of the current Google Go Project Tech lead in this GopherCon2015, the Go target is located in a highly concurrent cloud environment. The initial value of Gomaxprocs that identifies the number of concurrent system threads in Go 1.5 is changed from 1 to the number of CPU cores in the running environment.

Testgomaxprocs.go
Package Main

Import (
"FMT"
"Runtime"
)

Func Main () {
Fmt. Println (runtime. Gomaxprocs (-1))
Fmt. Println (runtime. Numgoroutine ())
}

The result of this code running on Go 1.4 (MAC OS X 4 core) is:

$go Run Testgomaxprocs.go
1
4

And in Go 1.5beta1, the result is:

$go Run Testgomaxprocs.go
4
4

Second, compile

"Simplifying cross-platform compilation"

1.5 Previous versions to implement cross-platform compilation, you need to re-execute the Make.bash under $GOROOT/SRC, set the environment variables for the target environment (GOOS and Goarch) before execution, and Go 1.5 greatly simplifies this process, making cross-platform compilation as simple as normal compilation. The following is a simple example:

Testcrosscompile.go
Package Main

Import (
"FMT"
"Runtime"
)

Func Main () {
Fmt. Println (runtime. GOOS)
}

On my Mac, the local compilation executes:
$go Build-o Testcrosscompile_darwin Testcrosscompile.go
$testcrosscompile _darwin
Darwin

Cross-platform compilation of target programs on Linux AMD64:

$GOOS =linux goarch=amd64 go build-o testcrosscompile_linux testcrosscompile.go

Upload testcrosscompile_linux to Ubuntu 14.04 to perform:
$testcrosscompile _linux
Linux

Although it's easy to compile commands across platforms from a user perspective, the fact is that go does a lot for you, and we can output the detailed process of compiling with the Build-x-v option, and you'll find that go goes first to $GOROOT/SRC recompile Runtime.a and some platform-related packages. There is too much information on compiling the output, it is not posted here. But in 1.5 this process is very fast (less than 10 seconds), compared to the 1.4 version of cross-platform compilation, is not a level, this is probably one of the benefits of the compiler go rewrite.

In addition to using go build directly, we can also use Go tool compile and Go tool link to compile the program, in fact go build also calls these two tools to complete the compilation process.

$go Tool Compile Testcrosscompile.go
Testcrosscompile.o
$go Tool Link TESTCROSSCOMPILE.O
A.out
$a. Out
Darwin

Go 1.5 Removes the previous compilation connection tools such as 6a,6l and integrates these tools into the Go tool. And the output of Go tool compile is changed to. o File by default, the linker output is changed to A.out by default.

"Dynamic Shared Library"

The individual is not very supportive of the go language to add support for dynamic shared libraries. So and the more than 10-year-old technology that has been "very big" in memory and disk space today seems to have lost the charm of the past. And the disadvantage of the Dynamic Sharing library: "DLL hell" will make the program follow the operation of the pain unceasingly. With the rise of lightweight containers such as Docker, the architecture for immutability (immutable architecture) has received more attention. People are more likely to operate on the container layer, and a pure static link application will have a natural advantage in terms of deployment and maintenance. So only adds complexity. If you are simply interoperating with other languages such as C, it seems that the use is not very broad (but may be used in the game or UI realm). However, go 1.5 also adds support for dynamic-link libraries, but it seems to be in the experimental phase, as seen in the doc instructions from Go tool compile and link.

Now that go 1.5 has supported the shared library, let's experiment with it. Let's start by planning the directory structure of the test repository:

$GOPATH
/src
/testsharedlib
/shlib
–lib.go
/app
/main.go

The code in Lib.go is simple:

Lib.go
Package Shlib

Import "FMT"

Export METHOD1
Func Method1 () {
Fmt. Println ("Shlib-method1")
}

For the method you want to export, use the export tag.

Let's compile this lib.go into shared lib, and note that it seems that only the Linux platform supports compiling the Go shared library at this time:

$ go build-buildmode=shared testsharedlib/shlib
#/tmp/go-build709704006/libtestsharedlib-shlib.so
Warning:unable to find RUNTIME/CGO.A

Compile OK, what is the meaning of that warning is not very understanding.

To get. So to be used by other go programs, you need to install. So in the relevant directory. Let's install it and try it out:

$ go install-buildmode=shared testsharedlib/shlib
Multiple Roots/home1/tonybai/test/go/go15/pkg/linux_amd64_dynlink &/home1/tonybai/.bin/go15beta1/go/pkg/ Linux_amd64_dynlink

Go tool incredibly tangled, do not know where to choose, one is $gopath/pkg/linux_amd64_dynlink, the other is $goroot/pkg/linux_amd64_dynlink, I am not sure this is not a bug.

After Google, I tried a solution on the Internet, first compiled the runtime's dynamic shared library:

$go install-buildmode=shared Runtime sync/atomic

After compiling the installation, you will see a more directory under $goroot/pkg: Linux_amd64_dynlink. The structure under this directory is as follows:

$ ls-r
.:
libruntime,sync-atomic.so Runtime runtime.a runtime.shlibname Sync

./runtime:
CGO.A Cgo.shlibname

./sync:
ATOMIC.A Atomic.shlibname

Here we see the previous warning mentioned RUNTIME/CGO.A, let's re-execute the build to see if we can eliminate warning:

$ go build-buildmode=shared testsharedlib/shlib
#/tmp/go-build086398801/libtestsharedlib-shlib.so
/home1/tonybai/.bin/go15beta1/go/pkg/tool/linux_amd64/link:cannot implicitly include RUNTIME/CGO in a shared library

This time even warnning have no, directly is an error. Here's a hint: You can't implicitly include RUNTIME/CGO in a shared library. In other words, when we build the dynamic shared library of Testshared/shlib, we also need an explicit link to runtime/cgo, which requires another command-line flag:-linkshared. Let's try it again:

$ go build-linkshared-buildmode=shared testsharedlib/shlib

This build succeeds! Let's try the install again:

$ go install-linkshared-buildmode=shared testsharedlib/shlib

The same success. And we found a shared library under $gopath/pkg/linux_amd64_dynlink:

$ ls-r
.:
Libtestsharedlib-shlib.so Testsharedlib

./testsharedlib:
SHLIB.A Shlib.shlibname

$ LDD libtestsharedlib-shlib.so
Linux-vdso.so.1 = (0x00007fff93983000)
libruntime,sync-atomic.so =/home1/tonybai/.bin/go15beta1/go/pkg/linux_amd64_dynlink/libruntime, Sync-atomic.so (0x00007fa150f1b000)
libc.so.6 =/lib/x86_64-linux-gnu/libc.so.6 (0x00007fa150b3f000)
libpthread.so.0 =/lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fa150921000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa1517a7000)

Okay, now that the shared library is compiled. Let's just use this shared library.

App/main.go

Package Main

Import (
"Testsharedlib/shlib"
)

Func Main () {
Shlib. METHOD1 ()
}

$ go build-linkshared main.go
$ LDD Main
Linux-vdso.so.1 = (0x00007fff579f7000)
libruntime,sync-atomic.so =/home1/tonybai/.bin/go15beta1/go/pkg/linux_amd64_dynlink/libruntime, Sync-atomic.so (0x00007fa8d6df2000)
libtestsharedlib-shlib.so =/home1/tonybai/test/go/go15/pkg/linux_amd64_dynlink/libtestsharedlib-shlib.so ( 0x00007fa8d6962000)
libc.so.6 =/lib/x86_64-linux-gnu/libc.so.6 (0x00007fa8d6586000)
libpthread.so.0 =/lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fa8d6369000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa8d71ef000)

$ main
Shlib-method1

Compile execution OK. From the output, we can see clearly the path of the. So and so that main relies on. Let's try again, if the Testsharedlib source directory is removed, you can also compile OK:

$ go build-linkshared main.go
Main.go:4:2:cannot Find Package "Testsharedlib/shlib" in any of:
/home1/tonybai/.bin/go15beta1/go/src/testsharedlib/shlib (from $GOROOT)
/home1/tonybai/test/go/go15/src/testsharedlib/shlib (from $GOPATH)

Go compiler can't find shlib, also say even dynamic link, we also need to have dynamic shared library source code, application can compile pass.

"InternalPackage"

Internal package is not the original of Go 1.5, in Go 1.4 has already proposed to the internal packages support. However, when Go 1.4 is released, the internal package can only be used for the go core Core pack under Goroot, and Gopath does not support internal packages at the user level. As planned, go 1.5 will extend the internal package mechanism to all repository. I thought 1.5beta1 and the internal package mechanism took effect, but actually, let's take a look at the sample code:

The test directory structure is as follows:

Testinternal/src
mypkg/
/internal
/foo
Foo.go
/pkg1
Main.go

otherpkg/
Main.go

According to the principle of internal package, the MYPKG/PKG1 code is expected to import "Mypkg/internal/foo", otherpkg/code is not import "Mypkg/internal/foo".

Foo.go
Package Foo

Import "FMT"

Func Foo () {
Fmt. Println ("Mypkg/internal/foo")
}

Main.go
Package Main

Import "Mypkg/internal/foo"

Func Main () {
Foo. Foo ()
}

Run Main.go under Pkg1 and otherpkg respectively:

mypkg/pkg1$ Go Run main.go
Mypkg/internal/foo

otherpkg$ Go Run main.go
Mypkg/internal/foo

You can see that there are no build error occurrences when executing under otherpkg. It seems that the internal mechanism is not effective.

Let's try the import $GOROOT some internal packages to see if they can be successful:

Package Main

Import (
"FMT"
"Image/internal/imageutil"
)

Func Main () {
Fmt. Println (Imageutil. DRAWYCBCR)
}

Let's run this code:

$go Run Main.go
0x6b7f0

No error is also present.

It is not clear why internal is still invalid in 1.5beta1. Does it have to wait for the final 1.5 release?

"Vendor"
The vendor mechanism is an experimental technology introduced by Go team to solve the dependency and management of Go third-party packages. You perform the following go ENV:

$go env
Goarch= "AMD64"
Gobin= "/users/tony/.bin/go15beta1/go/bin"
Goexe= ""
Gohostarch= "AMD64"
Gohostos= "Darwin"
Goos= "Darwin"
Gopath= "/users/tony/test/gotoolsprojects"
Gorace= ""
goroot= "/users/tony/.bin/go15beta1/go"
Gotooldir= "/users/tony/.bin/go15beta1/go/pkg/tool/darwin_amd64"
Go15vendorexperiment= ""
Cc= "Clang"
Gogccflags= "-fpic-m64-pthread-fno-caret-diagnostics-qunused-arguments-fmessage-length=0-fno-common"
cxx= "clang++"
cgo_enabled= "1"

From the results you will see a new go15vendorexperiment variable, which is the environment variable to control whether the vendor mechanism is turned on or not, which is not turned on by default. To turn on, you can set or export go15vendorexperiment=1 temporary settings in the environment variable file.

The vendor mechanism was temporarily decided to add to go 1.5 before the Go 1.5beta1 was released, and Russ Cox redesigned it on the basis of a proposal before Keith Rarick, with a general mechanism:

If There is a source directory D/vendor, then,
When compiling a source file within the subtree rooted at D,
Import "P" is interpreted as the import "d/vendor/p" if that exists.

When there is multiple possible resolutions,
The most specific (longest) path wins.

The short form must always be used:no import path can
Contain "/vendor/" explicitly.

Import comments is ignored in vendored packages.

Let's test this mechanism. First we temporarily open the vendor mechanism, export go15vendorexperiment=1, our test directory planning is as follows:

Testvendor
vendor/
tonybai.com/
foolib/
Foo.go
main/
Main.go

$GOPATH/src/tonybai.com/foolib/foo.go

Vendor/tonybai.com/foolib/foo.go
Package Foo

Import "FMT"

Func Hello () {
Fmt. Println ("foo in Vendor")
}

$GOPATH/src/tonybai.com/foolib/foo.go
Package Foo

Import "FMT"

Func Hello () {
Fmt. Println ("foo in Gopath")
}

Vendor and Gopath under the foo.go slightly different, mainly in the output content, in order to facilitate the subsequent distinction.

Now we compile the execution main.go

Main/main.go
Package Main

Import (
"Tonybai.com/foolib"
)

Func Main () {
Foo. Hello ()
}

$go Run Main.go
Foo in Gopath

Obviously the results are not the same as expected, and we'll look at Main.go's dependent package path through go list-json:

$go List-json
{
...
    Imports: [
        ' tonybai.com/foolib '
    ],
    "Deps": [
        "errors",
        "FMT",
        "io",
        " Math ",
       " OS ",
       " reflect ",
        "Runtime",
        "StrConv",
         "Sync",
        "sync/atomic",
         "Syscall",
        "Time",
        "Tonybai.com/foolib",
        "Unicode/utf8",
         "unsafe"
   ]
}

You can see that you do not see the vendor path, Main.go import is the $gopath foo. Is it the Go 1.5beta1 bug? I then looked at the various materials and finally got help in the commit log of Revison, which was last submitted before the Go 1.5BETA1 release:

Cmd/go:disable Vendoredimportpath for code outside $GOPATH
It was crashing.
This fixes the build for
Go15vendorexperiment=1 Go test-short Runtime

Fixes #11416.

change-id:i74a9114cdd8ebafcc9d2a6f40bf500db19c6e825
reviewed-on:https://go-review.googlesource.com/11964
Reviewed-by:russ Cox

From the commit log, the general meaning is that the vendor mechanism of the code outside of $gopath is disable (because of a bug). In other words, only the package under the $gopath path takes the vendor path into account in the import, and our code does not $gopath, we reset the $gopath.

$export GOPATH=~/TEST/GO/GO15
[Tony@tonydemacbook-air-2 ~/test/go/go15/src/testvendor/main] $go List-json
{

... ...
"Imports": [
"Testvendor/vendor/tonybai.com/foolib"
],
"Deps": [
"Errors",
"FMT",
"Io",
"Math",
"OS",
"Reflect",
"Runtime",
"StrConv",
"Sync",
"Sync/atomic",
"Syscall",
"Testvendor/vendor/tonybai.com/foolib",
"Time",
"Unicode/utf8",
"Unsafe"
]
}

This time you can see that the vendor mechanism is in effect. Execution Main.go:

$go Run Main.go
Foo in vendor

This is in line with the expected results.

As mentioned earlier, the shutdown of the vendor mechanism outside the Gopath is due to a bug that is believed to be enable when the release of Go 1.5 is officially released.

Third, summary

Go 1.5 also adds a lot of tools, such as Trace, but is not yet known how to use it because of incomplete documentation.

Go 1.5 Standard library also has a lot of small changes, this only to use when the specific in-depth understanding.

Go 1.5 is more of a change in the bone of the go language, i.e. runtime and compiler rewrite. Grammar is compatible with go 1, so the basic frozen, so from the external view, basically no change.

As for the performance of Go 1.5, the official argument is that some programs will become slower after compiling with 1.5 and some will be faster. The result of the official bench is that the overall ratio is 1.4 faster. But go 1.5 in terms of performance is mainly to reduce the GC delay, the subsequent version will be in the performance of further optimization, optimize the space is also larger, this runtime, the compiler from C to go, many places the go code is not the best, more automatic translation, believe that after Go team optimization, More idiomatic go code will make the go overall performance more excellent.

Bigwhite. All rights reserved.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.