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.