non-name *** on left side of :=
mean?
:=
must be pure identifiers and at least one of them must be a new variable name.
x[i]
), struct fields (x.f
), pointer dereferences (*p
) and qualified identifiers (aPackage.Value
) can't appear at the left side of :=
.
unexpected newline, expecting { ...
mean?
if true
{
}
for i := 0; i < 10; i++
{
}
var _ = []int
{
1, 2, 3
}
if true;
{
}
for i := 0; i < 10; i++;
{
}
var _ = []int;
{
1, 2, 3;
}
{
. To avoid these errors, we should rewrite the above code as the following.
if true {
}
for i := 0; i < 10; i++ {
}
var _ = []int {
1, 2, 3,
}
declared and not used
mean?
func f(x bool) {
var y = 1 // y declared but not used (as r-values)
if x {
y = 2 // here y is used as a left-hand-side value
}
}
package main
import (
"unsafe"
"fmt"
)
func main() {
type T1 struct {
a struct{}
x int64
}
fmt.Println(unsafe.Sizeof(T1{})) // 8
type T2 struct {
x int64
a struct{}
}
fmt.Println(unsafe.Sizeof(T2{})) // 16
}
new(T)
a sugar of var t T; (&t)
?
new
may be either on stack or on heap.
all goroutines are asleep - deadlock
mean?
sync/atomic
package must be 64-bit aligned, otherwise, calls to these functions may panic at run time.
package main
import (
"unsafe"
"fmt"
)
func main() {
// case 1:
var s = "abc"[0:0]
fmt.Println(s == "") // true
var addr = unsafe.StringData(s)
fmt.Println(addr) // <a-non-zero-value>
// case 2:
var x = 0.0
var y = -x
fmt.Println(y == 0) // true
var n = *(*uintptr)(unsafe.Pointer(&y))
fmt.Println(n) // 9223372036854775808
}
-gcflags "-l"
build option disables inlining globally, which will prevent all functions from being inline expanded.
//go:noinline
directive before a function declaration to prevent the function from being inlined, but this way is not guaranteed to always work in the future.
runtime.SetFinalizer
function. Generally, the finalizer function will be called before the object is garbage collected. But finalizers are never intended to be used as destructors of objects. The finalizers set by runtime.SetFinalizer
are not guaranteed to run. So you shouldn't rely on finalizers for your program correctness.
os.Open
to open many files but forgets to close them after using them, then the program will hold many file descriptors until the program exits. This is a classic example of resource leak. To avoid the program holding too many file descriptors, the maintainers of the os
package will set a finalizer on the every created os.File
object. The finalizer will close the file descriptor stored in the os.File
object. As mentioned above, the finalizers are not guaranteed to be called. They are just used to make the extent of resource leak as small as possible.
days := time.Date(year, month+1, 0, 0, 0, 0, 0, time.UTC).Day()
[1, 12]
and the start day of each month is 1
. The start time of a month m
in year y
is time.Date(y, m, 1, 0, 0, 0, 0, time.UTC)
. The arguments passed to time.Date
can be outside their usual ranges and will be normalized during the conversion. For example, January 32 will be converted to February 1.
time.Date
use examples in Go:
package main
import (
"time"
"fmt"
)
func main() {
// 2017-02-01 00:00:00 +0000 UTC
fmt.Println(time.Date(2017, 1, 32, 0, 0, 0, 0, time.UTC))
// 2017-01-31 23:59:59.999999999 +0000 UTC
fmt.Println(time.Date(2017, 1, 32, 0, 0, 0, -1, time.UTC))
// 2017-01-31 00:00:00 +0000 UTC
fmt.Println(time.Date(2017, 2, 0, 0, 0, 0, 0, time.UTC))
// 2016-12-31 00:00:00 +0000 UTC
fmt.Println(time.Date(2016, 13, 0, 0, 0, 0, 0, time.UTC))
// 2017-02-01 00:00:00 +0000 UTC
fmt.Println(time.Date(2016, 13, 32, 0, 0, 0, 0, time.UTC))
}
time.Sleep(d)
and the channel receive operation <-time.After(d)
?
time.Sleep(d)
will let the current goroutine enter sleeping sub-state, but still stay in running state, whereas, the channel receive operation <-time.After(d)
will let the current goroutine enter blocking state.
TrimLeft
and TrimRight
functions in the strings
and bytes
standard packages often return unexpected results, are there bugs in these function implementations?
strings
and bytes
standard packages. These functions can be categorized into two groups:
Trim
, TrimLeft
, TrimRight
, TrimSpace
, TrimFunc
, TrimLeftFunc
, TrimRightFunc
. These functions will trim all leading or trailing UTF-8-encoded Unicode code points (a.k.a. runes) which satisfy the specified or implied conditions (TrimSpace
implies to trim all kinds of white spaces). Each of the leading or trailing runes will be checked until one doesn't satisfy the specified or implied conditions.
TrimPrefix
, TrimSuffix
. The two functions will trim the specified prefix or suffix substrings (or subslices) as a whole.
TrimLeft
and TrimRight
functions as TrimPrefix
and TrimSuffix
functions when they use the trim functions the first time. Certainly, the return results are very possible not as expected.
package main
import (
"fmt"
"strings"
)
func main() {
var s = "abaay森z众xbbab"
o := fmt.Println
o(strings.TrimPrefix(s, "ab")) // aay森z众xbbab
o(strings.TrimSuffix(s, "ab")) // abaay森z众xbb
o(strings.TrimLeft(s, "ab")) // y森z众xbbab
o(strings.TrimRight(s, "ab")) // abaay森z众x
o(strings.Trim(s, "ab")) // y森z众x
o(strings.TrimFunc(s, func(r rune) bool {
return r < 128 // trim all ascii chars
})) // 森z众
}
fmt.Print
and fmt.Println
functions?
fmt.Println
function will always write a space between two adjacent arguments, whereas the fmt.Print
function will write a space between two adjacent arguments only if both of (the concrete values of) the two adjacent arguments are not strings.
fmt.Println
will write a newline character in the end, but the fmt.Print
function will not.
log.Print
and log.Println
functions?
log.Print
and log.Println
functions is the same as the first difference between the fmt.Print
and fmt.Println
functions described in the last question.
fmt.Print
, fmt.Println
and fmt.Printf
functions synchronized?
log
standard package instead when synchronizations are needed. You can call log.SetFlags(0)
to remove the prefix from each log line.
print
/println
functions and the corresponding print functions in the fmt
and log
standard packages?
print
/println
functions will write to standard error. The print functions in the fmt
standard package will write to standard output. The print functions in the log
standard package will write to standard error by default, though this can be changed using the log.SetOutput
function.
print
/println
functions can't take array and struct arguments.
print
/println
functions write the addresses of the underlying value parts of the argument, whereas the print functions in the fmt
and log
standard packages try to write the value literal of the dynamic values of the interface arguments.
print
/println
functions will not make the values referenced by the arguments of the calls escape to heap, whereas the print functions in the fmt
and log
standard packages will.
String() string
or Error() string
method, the print functions in the fmt
and log
standard packages will try to call that method when writing the argument, whereas the built-in print
/println
functions will ignore methods of arguments.
print
/println
functions are not guaranteed to exist in future Go versions.
math/rand
standard package and the crypto/rand
standard package?
math/rand
standard package are deterministic for a given seed. The produced random numbers are not good for security-sensitive contexts. For cryptographical security purpose, we should use the pseudo random numbers produced by the crypto/rand
standard package.
math.Round
function?
math.Round
function, but only since Go 1.10. Two new functions, math.Round
and math.RoundToEven
have been added since Go 1.10.
math.Round
function should be added to standard package or not. In the end, the proposal was adopted.
nil
identifier.
==
will panic at run time if the two dynamic types of the two interface values are identical and incomparable.
nil
values equal sometimes?
nil
. An interface value boxing nothing is a zero interface value, a.k.a, a nil interface value. However an interface value boxing a nil non-interface value doesn't box nothing, so it is not, and doesn't equal to, a nil interface value.
package main
import "fmt"
func main() {
var pi *int = nil
var pb *bool = nil
var x interface{} = pi
var y interface{} = pb
var z interface{} = nil
fmt.Println(x == y) // false
fmt.Println(x == nil) // false
fmt.Println(y == nil) // false
fmt.Println(x == z) // false
fmt.Println(y == z) // false
}
[]T1
and []T2
share the same underlying type even if the two different types T1
and T2
share the same underlying type?
unsafe
mechanisms only if the two slice types share the same underlying type. (This article lists the full list of value conversion rules.)
T1
and T2
share the same underlying type, type []T1
and []T2
are still different types, so their underlying types are also different, which means values of one of them can't be converted to the other.
[]T1
and []T2
are not same are:
[]T1
and []T2
to each other is not strong in practice.
map[T]T1
and map[T]T2
also don't share the same underlying type even if T1
and T2
share the same underlying type.
[]T1
can be converted to []T2
by using the unsafe
mechanisms, but generally this is not recommended:
package main
import (
"fmt"
"unsafe"
)
func main() {
type MyInt int
var a = []int{7, 8, 9}
var b = *(*[]MyInt)(unsafe.Pointer(&a))
b[0]= 123
fmt.Println(a) // [123 8 9]
fmt.Println(b) // [123 8 9]
fmt.Printf("%T \n", a) // []int
fmt.Printf("%T \n", b) // []main.MyInt
}
&T{}
, in Go. It is a short form of tmp := T{}; (&tmp)
. However, though &T{}
is legal, the literal T{}
is still not addressable.
aMap[key]
might return an element stored in map aMap
or not, which means aMap[key]
might still result in a zero value after (&aMap[key]).Modify()
is called. This would confuse many people. (Here Modify()
refers to a hypothetical method which would modify the value aMap[key]
).
struct {
// elements references an element sequence.
elements unsafe.Pointer
length int
capacity int
}
T
, why is the method set of *T
always a super set of the method set of T
, but not vice versa?
T
can call methods of type *T
, but only if the value of T
is addressable. Compilers will take the address of the T
value automatically before calling the pointer receiver methods. Because type T
can have values that are not addressable, not all values of type T
are capable of calling methods of type *T
.
*T
can always call methods of type T
. This is because it is always legal to dereference a pointer value.
*T
is always a super set of the method set of T
, but not vice versa.
T
, an implicit method with the same name and the same signature is automatically declared on type *T
. Please read methods for details.
func (t T) MethodX(v0 ParamType0, ...) (ResultType0, ...) {
...
}
// An implicit method of *T is automatically defined as
func (pt *T) MethodX(v0 ParamType0, ...) (ResultType0, ...) {
return (*pt).MethodX(v0, ...)
}
*T
, no methods with the same method name can be defined on T
any more. This is another explanation why the method set of *T
is always a super set of the method set of T
, but not vice versa. </p}
set
container type?
map[Tkey]struct{}
is often used as a set type.
[]byte
and []rune
values to strings?
byte
is an alias of type uint8
. In other words, byte
and uint8
are the same identical type. The same relation is for rune
and int32
.
rune
often is used to store a Unicode code point.
[]byte
and []rune
values can be explicitly and directly converted to strings, and vice versa.
package main
import "fmt"
func main() {
var s0 = "Go"
var bs = []byte(s0)
var s1 = string(bs)
var rs = []rune(s0)
var s2 = string(rs)
fmt.Println(s0 == s1) // true
fmt.Println(s0 == s2) // true
}
iota
mean?
iota
is used in constant declarations. In each constant declaration group, its value is N
in the Nth constant specification in that constant declaration group. This allows for easy declaration of related constants.
closed
function to check whether or not a channel is closed?
closed
functions and how to avoid using such a function.
The Go 101 project is hosted on Github. Welcome to improve Go 101 articles by submitting corrections for all kinds of mistakes, such as typos, grammar errors, wording inaccuracies, description flaws, code bugs and broken links.
If you would like to learn some Go details and facts every serveral days, please follow Go 101's official Twitter account @zigo_101.
reflect
standard package.sync
standard package.sync/atomic
standard package.