go语言为什么要反着写 go语言为什么要反着写字

go语言中的反射import (
"fmt"
"reflect"
)
func reflecType(x interface{}){
v := reflect.TypeOf(x)
fmt.Println("type:%v\n", v)
fmt.Println("type name:%v , rtpe kind:%v \n", v.getName(), v.getType())
}
type Cat struct{}
//通过反射设置变量的值
func reflectSetValue1(x interface{}){
v := reflect.ValueOf(x)
if v.Kind() == reflect.Int64{
v.SetInt(200) //修改的是副本, reflect 包会引发panic
}
}
//通过反射设置变量的值
func reflectSetValue2(x interface{}){
v := reflect.ValueOf(x)
//反射中使用Elem()获取指针对应的值
if v.Elem().Kind() == reflect.Int64{
v.Elem().SetInt(200)
}
}
func main(){
var a float32 = 3.14
reflectType(a) //type name:float32 type kind:float32
var b int64 = 100
reflectType(b) // type name :int64 type kind :int64
var c = Cat{}
reflectType(c) // type name :Cat type kind :struct
reflectSetValue1(b)
fmt.Println(b) //依然为100
reflectSetValue2(b)
}
讲讲go语言的结构体作为C语言家族的一员,go和c一样也支持结构体 。可以类比于java的一个POJO 。
在学习定义结构体之前,先学习下定义一个新类型 。
新类型 T1 是基于 Go 原生类型 int 定义的新自定义类型,而新类型 T2 则是 基于刚刚定义的类型 T1,定义的新类型 。
这里要引入一个底层类型的概念 。
如果一个新类型是基于某个 Go 原生类型定义的,那么我们就叫 Go 原生类型为新类型的底层类型
在上面的例子中,int就是T1的底层类型 。
但是T1不是T2的底层类型,只有原生类型才可以作为底层类型,所以T2的底层类型还是int
底层类型是很重要的,因为对两个变量进行显式的类型转换,只有底层类型相同的变量间才能相互转换 。底层类型是判断两个类型本质上是否相同的根本 。
这种类型定义方式通常用在 项目的渐进式重构,还有对已有包的二次封装方面
类型别名表示新类型和原类型完全等价 , 实际上就是同一种类型 。只不过名字不同而已 。
一般我们都是定义一个有名的结构体 。
字段名的大小写决定了字段是否包外可用 。只有大写的字段可以被包外引用 。
还有一个点提一下
如果换行来写
Age: 66,后面这个都好不能省略
还有一个点,观察e3的赋值
new返回的是一个指针 。然后指针可以直接点号赋值 。这说明go默认进行了取值操作
e3.Age等价于(*e3).Age
如上定义了一个空的结构体Empty 。打印了元素e的内存大小是0 。
有什么用呢?
基于空结构体类型内存零开销这样的特性,我们在日常 Go 开发中会经常使用空 结构体类型元素,作为一种“事件”信息进行 Goroutine 之间的通信
这种以空结构体为元素类建立的 channel , 是目前能实现的、内存占用最小的 Goroutine 间通信方式 。
这种形式需要说的是几个语法糖 。
语法糖1:
对于结构体字段,可以省略字段名 , 只写结构体名 。默认字段名就是结构体名
这种方式称为 嵌入字段
语法糖2:
如果是以嵌入字段形式写的结构体
可以省略嵌入的Reader字段,而直接访问ReaderName
此时book是一个各个属性全是对应类型零值的一个实例 。不是nil 。这种情况在Go中称为零值可用 。不像java会导致npe
结构体定义时可以在字段后面追加标签说明 。
tag的格式为反单引号
tag的作用是可以使用[反射]来检视字段的标签信息 。
具体的作用还要看使用的场景 。
比如这里的tag是为了帮助encoding/json标准包在解析对象时可以利用的规则 。比如omitempty表示该字段没有值就不打印出来 。
go语言操作符 ^ 和 &^很多语言都是采用 ~ 作为按位取反运算符 , Go 里面采用的是 ^。
如果作为二元运算符,^ 表示按位异或,即:对应位相同为 0,相异为 1 。
操作符 ^ , 按位置零,例如:z = x ^ y , 表示如果 y 中的 bit 位为 1,则 z 对应 bit 位为 0,否则 z 对应 bit 位等于 x 中相应的 bit 位的值 。
对于有符号的整数来说 , 是按照补码进行取反操作的(快速计算方法:对数 a 取反,结果为 -(a 1) ),对于无符号整数来说就是按位取反
计算过程
以3为例3在内存中补码为 0*** 0011
取反1*** 1100
-1操作1*** 1011
除符号位取反1*** 0100 结果为-4
-------------------------------------------
以9为例 9在内存中补码为 0*** 1001
取反1*** 0110
-1操作1*** 0101
除符号位取反1*** 1010 结果为-10
-------------------------------------------
以-5为例 -5在内存中为的补码为 1*** 1011
为什么呢
-5源码1*** 0101
除符号取反1*** 1010
1操作1*** 1011
-------------------------------------------
那么-5取反怎么算
补码 1***1011取反为 0***0100
因为符号位为0 , 所以是正数了,正数的补码反码源码都是一个,所以是4
===================================
再看-1
-1源码1*** 0001
除符号取反1*** 1110
1操作1*** 1111
补码 1*** 1111 取反为 0*** 0000
因为符号位为0,所以是正数了 , 正数的补码反码源码都是一个,所以是0
go语言取反输出的例子看这里
为什么GO语言把类型放在前面?当需要定义一个整形变量a 心里是这样想的:我现在需要一个整形的变量 , 我要定义它,于是我先写一个int,再思考它的名字 a ,于是就这么写出来了int a。而不是我写了个变量a,我得给它区分个类型int 。2. 在调用一个方法的时候,func(abdfsasdffdg int, bagressdgf string, csdgesredg bool)那个go函数看的很乱,程序员其实根本就不怎么看参数名字是什么,而只是看需要传入什么类型,注意力只在于int,string , bool这三个,如果如上那么写,反而影响了视线,乱系八糟的 。func(int adsfasdfsdaf, string asdfasfasf, bool gwegasgs),这么写我只注意类型,就不受名称影响了 。3. IDE自动提示go本身就是为快而生,定义一个结构变量Rectangle rectangle,当键盘敲下r时候,IDE会自动给出rectangle , 直接回车就出来了,反过来就的自己一个字母一个字母敲上去,蛋疼啊4. 至于go给出的解释 , 当遇到复杂函数时……一个项目中能写几个复杂函数,为了去解决这么一点小问题就把优势给牺牲了.
Go语言”奇怪用法“有哪些1 , go的变量声明顺序是:”先写变量名,再写类型名“,此与C/C的语法孰优孰劣,可见下文解释:
2 , go是通过package来组织的(与python类似),只有package名为main的包可以包含main函数,一个可执行程序有且仅有一个main包,通过import关键字来导入其他非main包 。
3,可见性规则 。go语言中,使用大小写来决定该常量、变量、类型、接口、结构或函数是否可以被外部包含调用 。根据约定,函数名首字母小写即为private,函数名首字母大写即为public 。
4,go内置关键字(25个均为小写) 。
5,函数不用先声明,即可使用 。
6,在函数内部可以通过 := 隐士定义变量 。(函数外必须显示使用var定义变量)
7,go程序使用UTF-8编码的纯Unicode文本编写 。
8,使用big.Int的陷阱:
9 , 从技术层面讲,go语言的语句是以分号分隔的 , 但这些是由编译器自动添加的,不用手动输入,除非需要在同一行中写入多个语句 。没有分号及只需少量的逗号和圆括号,使得go语言的程序更容易阅读 。
10,go语言只有一个循环结构——for循环 。
11,go里的自增运算符只有——“后”
12,go语言中的slice用法类似python中数组,关于slice的详细用法可见:
13,函数也是一个值,使用匿名函数返回一个值 。
14,函数闭包的使用 , 闭包是一个匿名函数值,会引用到其外部的变量 。
【go语言为什么要反着写 go语言为什么要反着写字】关于go语言为什么要反着写和go语言为什么要反着写字的介绍到此就结束了,不知道你从中找到你需要的信息了吗 ?如果你还想了解更多这方面的信息 , 记得收藏关注本站 。

    推荐阅读