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
	测试

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

字符串格式化

一般在输出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。

常量计算问题

常量分为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

位运算符

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

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

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<<3
 位号向左移动3位
 1
 1000  转换为10进制为8  我的理解是向左移动就是乘法 移动几位就是几次方  2^3=8
 
16>>3 
向左移动3位
10000
00010  转换为10进制 就是2   同样的 左移动就是除    16/(2^3)=2

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

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

指针操作

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

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

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

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

复制代码
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	

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

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

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

复制代码
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 小时前
基于YOLO算法的目标检测系统实现指南
算法·yolo·目标检测
flying robot1 小时前
js在浏览器执行原理
开发语言·javascript·ecmascript
代码小将3 小时前
Leetcode209做题笔记
java·笔记·算法
dhxhsgrx4 小时前
PYTHON训练营DAY25
java·开发语言·python
Musennn4 小时前
leetcode 15.三数之和 思路分析
算法·leetcode·职场和发展
风逸hhh6 小时前
python打卡day25@浙大疏锦行
开发语言·python
刚入门的大一新生6 小时前
C++初阶-string类的模拟实现与改进
开发语言·c++
CM莫问6 小时前
<论文>(微软)避免推荐域外物品:基于LLM的受限生成式推荐
人工智能·算法·大模型·推荐算法·受限生成
康谋自动驾驶7 小时前
康谋分享 | 自动驾驶仿真进入“标准时代”:aiSim全面对接ASAM OpenX
人工智能·科技·算法·机器学习·自动驾驶·汽车