go Type Identical &Value Assignability & Type Conversions
来源:互联网 发布:oracle数据触发器 编辑:程序博客网 时间:2024/06/06 07:43
1. Type identity
Two types are either identical or different.
Two named types are identical if their type names originate in the same TypeSpec. A named and an unnamed type are always different. Two unnamed types are identical if the corresponding type literals are identical, that is, if they have the same literal structure and corresponding components have identical types. In detail:
· Two array types are identical if they have identical element types and the same array length.
· Two slice types are identical if they have identical element types.
· Two struct types are identical if they have the same sequence of fields, and if corresponding fields have the same names, and identical types, and identical tags. Two anonymous fields are considered to have the same name. Lower-case field names from different packages are always different.
· Two pointer types are identical if they have identical base types.
· Two function types are identical if they have the same number of parameters and result values, corresponding parameter and result types are identical, and either both functions are variadic or neither is. Parameter and result names are not required to match.
· Two interface types are identical if they have the same set of methods with the same names and identical function types. Lower-case method names from different packages are always different. The order of the methods is irrelevant.
· Two map types are identical if they have identical key and value types.
· Two channel types are identical if they have identical value types and the same direction.
Given the declarations
type (
T0 []string
T1 []string
T2 struct{ a, b int }
T3 struct{ a, c int }
T4 func(int, float64) *T0
T5 func(x int, y float64) *[]string
)
these types are identical:
T0 and T0
[]int and []int
struct{ a, b *T5 } and struct{ a, b *T5 }
func(x int, y float64) *[]string and func(int, float64) (result *[]string)
T0 and T1 are different because they are named types with distinct declarations; func(int, float64) *T0 and func(x int, y float64) *[]string are different because T0 is different from []string.
2. Assignability
A value x is assignable to a variable of type T ("x is assignable to T") in any of these cases:
· x's type is identical to T.
· x's type V and T have identical underlying types and at least one of V or T is not a named type.
· T is an interface type and x implements T.
· x is a bidirectional channel value, T is a channel type, x's type V and T have identical element types, and at least one of V or T is not a named type.
· x is the predeclared identifier nil and T is a pointer, function, slice, map, channel, or interface type.
· x is an untyped constant representable by a value of type T.
3. Conversions
Conversions are expressions of the form T(x) where T is a type and x is an expression that can be converted to type T.
Conversion = Type "(" Expression [ "," ] ")" .
If the type starts with the operator * or <-, or if the type starts with the keyword func and has no result list, it must be parenthesized when necessary to avoid ambiguity:
*Point(p) // same as *(Point(p))
(*Point)(p) // p is converted to *Point
<-chan int(c) // same as <-(chan int(c))
(<-chan int)(c) // c is converted to <-chan int
func()(x) // function signature func() x
(func())(x) // x is converted to func()
(func() int)(x) // x is converted to func() int
func() int(x) // x is converted to func() int (unambiguous)
A constant value x can be converted to type T in any of these cases:
常量字面量复制给类型T变量主要涉及到的就是 数字常量字面量
· x is representable by a value of type T.
· x is a floating-point constant, T is a floating-point type, and x is representable by a value of type T after rounding using IEEE 754 round-to-even rules, but with an IEEE -0.0 further rounded to an unsigned 0.0. The constant T(x)is the rounded value.
· x is an integer constant and T is a string type. The same rule as for non-constant x applies in this case.
Converting a constant yields a typed constant as result.
uint(iota) // iota value of type uint
float32(2.718281828) // 2.718281828 of type float32
complex128(1) // 1.0 + 0.0i of type complex128
float32(0.49999999) // 0.5 of type float32
float64(-1e-1000) // 0.0 of type float64
string('x') // "x" of type string
string(0x266c) // "♬" of type string
MyString("foo" + "bar") // "foobar" of type MyString
string([]byte{'a'}) // not a constant: []byte{'a'} is not a constant
(*int)(nil) // not a constant: nil is not a constant, *int is not a boolean, numeric, or string type
int(1.2) // illegal: 1.2 cannot be represented as an int
string(65.0) // illegal: 65.0 is not an integer constant
A non-constant value x can be converted to type T in any of these cases:
· x is assignable to T.
· x's type and T have identical underlying types.
· x's type and T are unnamed pointer types and their pointer base types have identical underlying types.
· x's type and T are both integer or floating point types.
· x's type and T are both complex types.
· x is an integer or a slice of bytes or runes and T is a string type.
· x is a string and T is a slice of bytes or runes.
Specific rules apply to (non-constant) conversions between numeric types or to and from a string type. Theseconversions may change the representation of x and incur a run-time cost. All other conversions only change the type but not the representation of x.
There is no linguistic mechanism to convert between pointers and integers. The package unsafe implements this functionality under restricted circumstances.
Conversions between numeric types
For the conversion of non-constant numeric values, the following rules apply:
1 When converting between integer types, if the value is a signed integer, it is sign extended to implicit infinite precision; otherwise it is zero extended. It is then truncated to fit in the result type's size. For example, if v := uint16(0x10F0), then uint32(int8(v)) == 0xFFFFFFF0. The conversion always yields a valid value; there is no indication of overflow.
2 When converting a floating-point number to an integer, the fraction is discarded (truncation towards zero).
3 When converting an integer or floating-point number to a floating-point type, or a complex number to another complex type, the result value is rounded to the precision specified by the destination type. For instance, the value of a variable x of type float32 may be stored using additional precision beyond that of an IEEE-754 32-bit number, but float32(x) represents the result of rounding x's value to 32-bit precision. Similarly, x + 0.1 may use more than 32 bits of precision, but float32(x + 0.1) does not.
In all non-constant conversions involving floating-point or complex values, if the result type cannot represent the value the conversion succeeds but the result value is implementation-dependent.
Conversions to and from a string type
主要涉及 string 和 []byte、[] rune 转换
1 Converting a signed or unsigned integer value to a string type yields a string containing the UTF-8 representation of the integer. Values outside the range of valid Unicode code points are converted to "\uFFFD".
整形转换为字符串,将整形数值看作Unicode 码进行转译,如果该整数代表的数值不能转换为Unicode码,则直接转为\ufffd
string('a') // "a"
string(-1) // "\ufffd" == "\xef\xbf\xbd"
string(0xf8) // "\u00f8" == "ø" == "\xc3\xb8"
type MyString string
MyString(0x65e5) // "\u65e5" == "日" == "\xe6\x97\xa5"
2 Converting a slice of bytes to a string type yields a string whose successive bytes are the elements of the slice.
[]byte转换为string 就是该slice每个字节所代表的字符构成的字符串
string([]byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'}) // "hellø"
string([]byte{}) // ""
string([]byte(nil)) // ""
type MyBytes []byte
string(MyBytes{'h', 'e', 'l', 'l', '\xc3', '\xb8'}) // "hellø"
3 Converting a slice of runes to a string type yields a string that is the concatenation of the individual rune values converted to strings.
[]rune 转换为string ,会进行译码,将rune存放的unicode编码转换为具体的字符值
string([]rune{0x767d, 0x9d6c, 0x7fd4}) // "\u767d\u9d6c\u7fd4" == "白鵬翔"
string([]rune{}) // ""
string([]rune(nil)) // ""
type MyRunes []rune
string(MyRunes{0x767d, 0x9d6c, 0x7fd4}) // "\u767d\u9d6c\u7fd4" == "白鵬翔"
4 Converting a value of a string type to a slice of bytes type yields a slice whose successive elements are the bytes of the string.
String 转 []byte 直接将字符串的每个字符存入[]byte 每个字节中
[]byte("hellø") // []byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'}
[]byte("") // []byte{}
MyBytes("hellø") // []byte{'h', 'e', 'l', 'l', '\xc3', '\xb8'}
5 Converting a value of a string type to a slice of runes type yields a slice containing the individual Unicode code points of the string.
String 转 []rune 会将string每个字符的unicode码存入[]rune中
[]rune(MyString("白鵬翔")) // []rune{0x767d, 0x9d6c, 0x7fd4}
[]rune("") // []rune{}
MyRunes("白鵬翔") // []rune{0x767d, 0x9d6c, 0x7fd4}
- go Type Identical &Value Assignability & Type Conversions
- Type Conversions in Cpp
- Effective C++ 19. type conversions
- Go-Type
- Type conversions with implicit and explicit operators
- 类型转换一:Type conversions One:
- c++教程(二十二:Type conversions)
- Go语言interface的value.(type)使用小技巧
- Value Type 和 Reference Type
- Value Type And Reference Type
- go interface type
- Type-length-value数据格式
- Case: Hibernate: Value Type
- new (addr)type(value)
- Type-length-value
- Value Of Type
- data-type,data-value
- Value and type
- JS中创建函数的三种方式及区别
- moehydrogen.SchoolOlympiadProject
- 为Docker容器设置固定IP实现网络联通(2)——通过Python脚本实现并解决pipework缺陷
- error MSB8031 Building an MFC project for a non-Unicode character set is deprecated.
- Java线程之1.4版多生产多消费者示例(三)
- go Type Identical &Value Assignability & Type Conversions
- ASCLL码表
- Loadrunner中Throughput(吞吐量)的分析与计算
- 添加、获取cookie
- 在幼儿园管理系统中,会议管理>申请会议模块:添加会议记录(提交表单)的时候报:404错误!
- java之redis篇(spring-data-redis整合)(很好)
- php、ThinkPHP禁用浏览器缓存
- ios使用友盟分享到QQ/微信时时如何判断手机上是否安装了QQ以及微信的客户端
- BMC