无类型值可以分为以下几类:`UntypedBool`、`UntypedInt`、`UntypedRune`、`UntypedFloat`、`UntypedComplex`、`UntypedString` 以及 `UntypedNil`(Go 称它们为基础类型,other basic kinds are available for the concrete types like `uint8`)。一个无类型值可以赋值给一个从基础类型中派生的具名类型;例如:
Go does not provide exceptions or structured error handling. Instead, it handles errors by returning them in a second or later return value:
```
func Read(p []byte) (n int, err error)
// Built-in type:
type error interface {
Error() string
}
```
Errors have to be checked in the code, or can be assigned to `_`:
```
n0, _ := Read(Buffer) // ignore error
n, err := Read(buffer)
if err != nil {
return err
}
```
There are two functions to quickly unwind and recover the call stack, though: `panic()` and `recover()`. When `panic()` is called, the call stack is unwound, and any deferred functions are run as usual. When a deferred function invokes `recover()`, the unwinding stops, and the value given to `panic()` is returned. If we are unwinding normally and not due to a panic, `recover()` simply returns `nil`. In the example below, a function is deferred and any `error` value that is given to `panic()` will be recovered and stored in an error return value. Libraries sometimes use that approach to make highly recursive code like parsers more readable, while still maintaining the usual error return value for public functions.
```
func Function() (err error) {
defer func() {
s := recover()
switch s := s.(type) { // type switch
case error:
err = s // s has type error now
default:
panic(s)
}
}
}
```
### Arrays 和 slices
As mentioned before, an array is a value type and a slice is a pointer into an array, created either by slicing an existing array or by using `make()` to create a slice, which will create an anonymous array to hold the elements.
```
slice1 := make([]int, 2, 5) // 5 elements allocated, 2 initialized to 0
slice2 := array[:] // sliced entire array
slice3 := array[1:] // slice of array without first element
```
There are some more possible combinations for the slicing operator than mentioned above, but this should give a good first impression.
A slice can be used as a dynamically growing array, using the `append()` function.
```
slice = append(slice, value1, value2)
slice = append(slice, arrayOrSlice...)
```
Slices are also used internally to represent variable parameters in variable length functions.
### Maps
Maps are simple key-value stores and support indexing and assigning. They are not thread-safe.
```
someValue := someMap[someKey]
someValue, ok := someMap[someKey] // ok is false if key not in someMap