基本数据类型和string之间的转换

(1) 基本类型转string
  • 使用 fmt.Sprintf(“%参数”, 表达式)

a. 通用:

b. 布尔值:

c. 整数:

d. 浮点数与复数的两个组分:

e. 字符串和[]byte:

f. 指针:

  • 使用 strconv 包的函数
func FormatBool(b bool) string
func FormatInt(i int64, base int) string
func FormatUint(i uint64, base int) string
func FormatFloat(f float64, fmt byte, prec, bitSize int) string
func Itoa(i int) string    // ItoaFormatInt(i, 10) 的简写

base:指定进制(2到36)
fmt:表示格式:'f'(-ddd.dddd)、'b'(-ddddp±ddd,指数为二进制)、'e'(-d.dddde±dd,十进制指数)、'E'(-d.ddddE±dd,十进制指数)、'g'(指数很大时用 'e' 格式,否则 'f' 格式)、'G'(指数很大时用 'E' 格式,否则 'f' 格式)。
prec:精度(排除指数部分):对 'f'、'e'、'E',它表示小数点后的数字个数;对 'g'、'G',它控制总的数字个数。如果 prec 为-1,则代表使用最少数量的、但又必需的数字来表示 f。
bitSize:表示 f 的来源类型(32:float32、64:float64),会据此进行舍入。

(2) string 转基本类型
func ParseInt(s string, base int, bitSize int) (i int64, err error)
func ParseUint(s string, base int, bitSize int) (n uint64, err error)
func ParseFloat(s string, bitSize int) (f float64, err error)
func FormatBool(b bool) string
func Atoi(s string) (i int, err error)    // AtoiParseInt(s, 10, 0)的简写。

base:指定进制(2到36),如果base为0,则会从字符串前置判断,"0x"是16进制,"0"是8进制,否则是10进制。
bitSize:指定结果必须能无溢出赋值的整数类型,0、8、16、32、64 分别代表 int、int8、int16、int32、int64;简单的说,如果这个 string 所表示的真实值超出了 baseSize 所指定的类型的范围,那么就会发生溢出,虽然这个返回值是 64 位的,然并卵,看下面的例子就明白了。

var str string = "999"
var num int64
num, _ = strconv.ParseInt(str, 108)
fmt.Println(num)  // 结果是 127

值类型和引用类型

值类型: int、float、string、bool、数组、结构体struct
引用类型:指针、切片slice、map、管道channel、interface

注意:数组也是值类型,跟其他语言不同。

值类型通常在栈中分配,引用类型通常在堆中分配,当没有任何一个引用指向该引用类型的地址时,GC 将其回收。

这里说的是通常,而不是绝对,这是由于 Golang 中的逃逸机制导致的,这个逃逸机制以后再说。

空标识符

_ 是一个特殊的标识符,称为空标识符。它可以代表其他任何的标识符,但是它对应的值会被忽略,所以仅能作为占位符使用。

访问级别

Golang 中没有 public、private 等访问修饰符,而是规定,常量名、变量名、函数名的首字母如果是大写的,则可以被其他包访问,如果是小写的,则其他包不能访问。

运算符

(1) 取模

a % b 的运算规则是 a - a / b * b

(2) ++ 和 --

Golang 中,只有 i++,而没有 ++i
自增和自减只能当做一个独立的语句使用,j = i++if i++ > 0 等写法都是错的。

(3) 三元运算符

Golang 不支持三元运算符,请用 if else

if

基本语法:

if 条件表达式 {
    语句块
else {
    语句块
}
  • 条件表达式不需要() 括起来,在一般情况下,加了 () 也不会报错,但是不建议这么做。如果条件表达式用有定义变量(见下文),那么加了 () 会报错。
  • 语句块必须包含在 {} 中,即便该语句块中只包含一条语句。(自动加分号导致)
  • else 必须写在 if 语句块的 } 后面,不能另起一行。(自动加分号导致)
  • 允许在条件表达式中声明一个变量,以分号结尾,在这个变量后面再写条件表达式,这个变量的作用域只在该条件逻辑块内。
if age := 20; age > 18 {
    fmt.Println("已成年")
else {
    fmt.Println("未成年")
}
Go:学习笔记兼吐槽(2)-LMLPHP

switch

基本语法

switch 表达式 {
    case 表达式1:
        语句块
    case 表达式2, 表达式3,...:
        语句块
    default:
        语句块
}
  • case 后面可以跟多个表达式,逗号隔开,只要其中一个匹配成功就可进入
  • case 的语句块中不需要加 break,默认情况下,语句块执行完成后就退出 switch
  • switch 后可以不带表达式,类似 if else 分支来使用
var age int = 20
switch  {
    case age > 18:
        fmt.Println("已成年")
    default:
        fmt.Println("未成年")
}
  • switch 后也可以直接声明一个变量,以分号结束,和 if 类似,但这种写法不推荐使用。
switch age := 20; {
    case age > 18:
        fmt.Println("已成年")
    default:
        fmt.Println("未成年")
}
  • switch 穿透:在 case 语句块后增加 fallthrough,则会执行下一个 case。只能穿透一层 case
  • switch 语句还可以被用于 type-switch 来判断某个 interface 变量中实际指向的变量类型。

for循环

基本语法:

for i := 1 ; i < 10; i++ {
    语句块
}

也可以将循环变量定义或循环变量迭代写在其他地方,但分号不能省略,这点跟 .net 等语言是一样的。

i := 1 
for ;i < 10; i++ {
    语句块
}

第二种写法,for 后面可以仅有循环条件判断

i := 1 
for i < 10  {
    语句块
    i++
}

第三种写法:

for {
    语句块
}

这种写法等价于for ; ; {},是一个死循环,通常需要配合 break 使用。
Golang 中没有 while 和 do while,如果要实现类似的效果,就只能用这个方式。

for range

for range 方式用于遍历容器类型,如字符串、数组、切片、映射。

var str string = "hello"
for index, value := range str {
    fmt.Printf("%v %c\n", index, value)
}

for range 遍历字符串的时候是按字节的方式遍历的,看如下示例:

var str1 string = "hello 北京"
for index, value := range str1 {
    fmt.Printf("%v %c\n", index, value)
}

//运行结果
0 h
1 e
2 l
3 l
4 o
5
6 北
9 京    //注意这里 index 从 6 直接跳到了 9,因为 UTF-8 编码一个汉字占 3 个字节

break 和 continue

break 用于跳出循环,在 .net 等语言中,break 只能用于跳出当前循环,而在 Golang 中,可以通过标签指明要跳出哪一层的循环。有点类似 goto 了。

lable1:
for i := 0; i < 10; i++{
    for j := 0; j < 10; j ++{
        if j == 2{
            break lable1
        }
        fmt.Println(j)
    }
}

continuebreak 一样,也可以通过标签指定要继续的是哪一层循环。

01-15 11:44