• go语法入门2


    字符串

    使用双引号或反引号引起来的任意个字符。它是字面常量

    func main() {
    	var a = "abc\n测试"     //  \n换行
    	fmt.Println(a)
    }
    abc
    测试
    
    func main() {
    	var a = "abc\n\t测试"   \\换行后在tab
    	fmt.Println(a)
    }
    abc
    	测试
    	
    func main() {
    	var a = `abc
    	测试`                \\   ``反引号   反引号内不支持转义字符
    	fmt.Println(a)
    }
    abc
    	测试
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    func main() {
    	var a = `json:"name"`    // 字符串里面如果有双引号,使用反引号定义方便,不用使用转义符 直接使用反引号更加方便     "json:\"name\"" 等价 `json:"name"`   
    	fmt.Println(a)
    } 
    
    json:"name"
    
    
    func main() {
    	var a = "abc" + "efg"
    	fmt.Println(a)
    }
    abcefg
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    字符串格式化

    一般在输出fmt.Printf(“%+v\n”, fmt)

    • %v 适合所有类型数据,调用数据的缺省打印格式\
      • %+v对于结构体,会多打印出字段名
    • %#v 对于结构体,有更加详细的输出
    • %T 打印值的类型
    • %% 打印百分号本身

    整数

    • %b 二进制;%o 八进制;%O 八进制带0o前缀;%x 十六进制小写;%X16 进制大写
    • %U 把一个整数用Unicode格式打印。例如 fmt.Printf(“%U, %x, %c\n”, 27979, 27979,
      27979) 输出 U+6D4B, 6d4b
    • %c 把rune、byte的整型值用字符形式打印
    • %q 把一个整型当做Unicode字符输出,类似%c,不过在字符外面多了单引号。q的意思就是quote
      浮点数
    • %e、%E 科学计数法
    • %f、%F 小数表示法,最常用
    • %g 内部选择使用%e还是%f以简洁输出;%G 选择%E或%F

    字符串或字节切片

    • %s 字符串输出。如果是rune切片,需要string强制类型转换
    • %q 类似%s,外部加上双引号。q的意思就是quote

    指针

    • %p 十六进制地址

    输出函数

    输出到标准输出

    • Print:使用缺省格式输出,空格分割
    • Println:使用缺省格式输出,空格分割,最后追加换行
    • Printf:按照指定的格式符输出

    输出到字符串,经常用来拼接字符串

    • Sprint:相当于Print,不过输出为string
    • Sprintln:相当于Println,不过输出为string
    • Sprintf:相当于Printf,不过输出为string

    操作符

    逻辑运算真值表

    外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

    理解:

    与逻辑相当于乘法:A×B=F

    或逻辑相当于加法:A+B=F,但是 不是二进制,不往上进位

    非逻辑:取反

    算数运算符

    func main() {
    	var a = 5 / 2   //2  除法 
    	fmt.Printf("%v\n", a)
    }
    
    
    func main() {
    	var a = 5 % 2     //1  取余
    	fmt.Printf("%v\n", a)
    }
    
    ++、--只能是i++、i--,且是语句,不是表达式。也就是说,语句不能放到等式、函数参数等地方。例
    如, fmt.Println(a++) 是语法错误。
    没有++i、--i。
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    常量计算问题

    常量分为typed类型化常量和untyped常量

    类型不同 不能进行计算
    
    
    var a int = 1
    var b float32 = 2.3
    fmt.Println(a * b) // 错误,int和float32类型不同   需要进行强制类型转换
    
    但是
    fmt.Println(1 * 2.3)   不报错
    因为根据语法糖 1已经被隐式类型转换为float64类型
    
    fmt.Println(1 * 2.3)
    fmt.Printf("%T %[1]g\n", 1*2.3)  //%g是float的类型
    2.3
    float64 2.3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    位运算符

    &位与、|位或、异或、&位清空、<<、>>

    2&1, 2&^1, 3&1, 3&^1

    &^1 代表的意思是将1的位置对应的全列全部清空为0 其他位上面的数值直接落下去

    ^异或 转化为2进制后相同的位位0 不同的位为1

    a: 00001100
    b:00000100
    c: 00001000

    2&1					 2&^1								3&1						 3&^1
    10					 10									11						 11
    01 相乘为0  		   00  直接成为10 为2                   01 相乘转换10进制 为1 	   01
    																				 10 为2
    
    • 1
    • 2
    • 3
    • 4

    2|1, 3^3, 1<<3 ,16>>3 , 2^1

    2|1					           3^3                    3&1
    10								11					  11	
    01 相加为11 转换为10进制为3  	  11					01
    								00 转换为10进制为0 	  01
    
    • 1
    • 2
    • 3
    • 4
     1<<3
     位号向左移动3位
     1
     1000  转换为10进制为8  我的理解是向左移动就是乘法 移动几位就是几次方  2^3=8
     
    16>>3 
    向左移动3位
    10000
    00010  转换为10进制 就是2   同样的 左移动就是除    16/(2^3)=2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    x&y ,位与本质就是按照y有1的位把x对应位的值保留下来。
    x&^y,位清空本质就是先把y按位取反后的值,再和x位与,也就是y有1的位的值不能保留,被清空,原
    来是0的位被保留。换句话说,就是按照y有1的位清空x对应位。

    比较运算符

    比较运算符组成的表达式,返回bool类型值。成立返回True,不成立返回False
    ==、!=、>、<、>=、<=

    1 && 5 > 3 在go中,不可以用逻辑运算符来计算非bool型
    在其他语言中,可以做某些类型值等效看做bool值。在逻辑运算中,1看做真true,0看做false,-1看做真;""看做false,非空字符串看做true

    短路

    逻辑运算符

    &&、||、!

    	短路
    		true || false || false || false      为true   || 一真则真
    		false || true || false || false      为true
    		false && true && false && true       为false  && 一假则假
    		true || false && true                 为true
    
    • 1
    • 2
    • 3
    • 4
    • 5

    5 > 3 && “abc” < “xyz” 逻辑运算符两边必为bool类型

    指针操作

    数据是放在内存中,内存是线性编址的。任何数据在内存中都可以通过一个地址来找到它。

    标识符的本质,指向,编译后被翻译成内存地址
    是一种类型的值,本质上是一个大整数,简单认为整个整数就是内存中的门牌号码
    *int 指向int类型数据的指针
    0xc000018088 表示门牌号码
    门里面房间里面住着数据
    
    • 1
    • 2
    • 3
    • 4
    • 5

    &是取地址 内存的存放位置

    *指针变量,通过指针取值

    func main() {
    	a := 101
    	b := &a
    	fmt.Printf("%T %[1]v\n", b)
    }
    *int 0xc00001a098   b的类型是int类型
    
    
    	c := *b
    	fmt.Printf("%+v\n", c)  //c 101  
    但是在这里c的地址是否和a的地址相同 
    答案是不同的   这里相当于a创建了一个副本101 这个副本在内存中有个独立的位置  而c指向的是这个内存
    更加清晰的理解就是 取到了101的值 在定义赋值给c  那初始化赋值不就是重新开辟新的内存地址
    func main() {
    	a := 101
    	b := &a
    	fmt.Printf("%T %[1]v\n", b)
    	c := *b
    	fmt.Printf("%v\n", &c)
    
    }
    *int 0xc00001a098
    0xc00001a0b8	
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    func main() {
    	a := 101
    	b := &a
    	c := *b
    	fmt.Println(1, a == c)
    	fmt.Println(2, b == &c)
    	fmt.Println(b, &b, c, &c)
    }
    1 true
    2 false
    0xc00001a098 0xc00000a028 101 0xc00001a0b0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    func main() {
    	a := 101
    	b := &a
    	c := *b
    	fmt.Println(1, a == c)
    	fmt.Println(2, b == &c)
    	fmt.Println(b, &b, c, &c)
    	var d = a
    	fmt.Println(3, d == a)
    	fmt.Println(4, &d == &a, &a, &d)
    } 
    1 true
    2 false
    0xc00001a088 0xc00000a028 101 0xc00001a0a0
    3 true
    4 false 0xc00001a088 0xc00001a0d0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    只要用指针取值 必定会重新创建一个新的内存地址

    fmt.Println(1, a == c)
    fmt.Println(2, b == &c)
    fmt.Println(b, &b, c, &c)
    var d = a
    fmt.Println(3, d == a)
    fmt.Println(4, &d == &a, &a, &d)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    }
    1 true
    2 false
    0xc00001a088 0xc00000a028 101 0xc00001a0a0
    3 true
    4 false 0xc00001a088 0xc00001a0d0

    
    只要用指针取值 必定会重新创建一个新的内存地址
    
    
    • 1
    • 2
    • 3
  • 相关阅读:
    【Python】Windows跟随程序启动和关闭系统代理
    python爱心代码高级
    FreeRTOS学习笔记-任务
    JSX语法
    c语言中的fputc、fputs
    Canal + MySQL + Zookeeper + Kafka 数据实时同步
    __proto__和protype的区别
    ros2原来本是一个通信协议
    单片机液晶多级菜单的程序写法
    第十九章绘图
  • 原文地址:https://blog.csdn.net/xiaolong1155/article/details/134249106