【Golang】基本类型和运算符

Golang对值之间有比较严格的限制,只有两个类型相同的值才可以比较,

格式化输出时可以使用%t表示你要输出的值是布尔类型

对于布尔值而言好的命名能很好提高代码的可读性。例如以is或者Is开头的isSorted、isFinished、isVisible。

数字类型

Go语言没有float类型只float32和float64,没有double类型。

float32精确到瞎弄书店后7位,float64精确到后15位,由于精确度的原因在使用==或!=时要小心!(正式使用前测试精确度较高的运算)

应该尽可能使用float64, 因为  math包中所有有关数学的函数都要求接受这个类型。

可以通过加前缀0来表示8进制数,通过加0x表示16进制数,用e来表示10的连乘。(1e3=1000)。

你可以使用a:=uint64(0)来同时完成类型的转换和赋值。

Go不允许不同类型之间的混合使用,但是对于常量的类型限制非常少,因此运行常量之间的混合使用。

以下程序无法通过编译:

package main
func main(){
    var a int
    var b int32
    a=15
    b=a+a//编译错误
    b=b+5//因为5是常量所以编译成功
}

尝试编译,编译器显示

同时int16也不能隐式转换为int32。

所以需要显示转换解决问题

package main

import "fmt"

func main(){
    var n int16=34
    var m int32
    //m=n
    m=int32(n)
    fmt.Printf("%d\n",m)
    fmt.Printf("%d\n",n)
}

合并定义和声明在一行 

合并后不显示转换

显示转换后成功编译

格式化说明符

在格式化字符串 %x %X表示格式化16进制数,%g用于格式化浮点数,%f输出浮点数,%e输出科学计数法,%0d用于输出定长的整数,%n.mg用于表示n宽度并精确到小数点后m位,除了使用g还可以使用e或者f,例如%5.2e来输出3.4的结果为3.40e+00 n

不够长就前补0

数字值转换

下面这个例子展示如何安全地从 int 型转换为 int8:?

func Uint8FromInt(n int) (uint8, error) {
    if 0 <= n && n <= math.MaxUint8 { // conversion is safe
        return uint8(n), nil
    }
    return 0, fmt.Errorf("%d is out of the uint8 range", n)
}

或者安全地从 float64 转换为 int:

func IntFromFloat64(x float64) int {
    if math.MinInt32 <= x && x <= math.MaxInt32 { // x lies in the integer range
        whole, fraction := math.Modf(x)
        if fraction >= 0.5 {
            whole++
        }
        return int(whole)
    }
    panic(fmt.Sprintf("%g is out of the int32 range", x))
}

实际存的数字超出你要转换到的类型的取值范围的话,则会引发 panic。

学习代码

package main

import (
	"fmt"
	"io"
	"math/rand"
	"strconv"
	"strings"
	"time"
	"unicode/utf8"
)

/*
整型和浮点型数字,int\uint32 位os,32 位(4 个字节),64os,64 位(8 个字节)。
Go 语言中没有 float 类型。(Go 语言中只有 float32 和 float64)没有 double 类型。
?怎么表示
整数:
int8(-128 -> 127)
int16(-32768 -> 32767)
int32(-2,147,483,648 -> 2,147,483,647)
int64(-9,223,372,036,854,775,808 -> 9,223,372,036,854,775,807)
无符号整数:
uint8(0 -> 255)
uint16(0 -> 65,535)
uint32(0 -> 4,294,967,295)
uint64(0 -> 18,446,744,073,709,551,615)
浮点型(IEEE-754 标准):
float32(+- 1e-45 -> +- 3.4 * 1e38)
float64(+- 5 1e-324 -> 107 1e308)

你应该尽可能地使用 float64,因为 math 包中所有有关数学运算的函数都会要求接收这个类型。

!Go 中不允许不同类型之间的混合使用,但是对于常量的类型限制非常少

*/

/*
复数
complex64 (32 位实数和虚数)
complex128 (64 位实数和虚数)
在使用格式化说明符时,可以使用 %v 来表示复数,但当你希望只表示其中的一个部分的时候需要使用 %f
*/

/*
位运算
&同1为1
|有1为1
按位异或 ^ 不同为1
位清除 &^:将指定位置上的值设置为 0。


-01 ^ 10 = -11

bitP >> n。
bitP 的位向右移动 n 位,左侧空白部分使用 0 填充
负数变补码 负号不取反,其他取反+1 再^1 之后结果取反+1
位左移常见实现存储单位的用例

使用位左移与 iota 计数配合可优雅地实现存储单位的常量枚举:
*/

/*
随机数
*/

/*
运算符优先级
优先级     运算符
 7      ^ !
 6      * / % << >> & &^
 5      + - | ^
 4      == != < <= >= >
 3      <-
 2      &&
 1      ||
*/

/*
字符类型
var ch byte = 65 或 var ch byte = '\x41'
(\x 总是紧跟着长度为 2 的 16 进制数)
另外一种可能的写法是 \ 后面紧跟着长度为 3 的八进制数,例如:\377。
不过 Go 同样支持 Unicode(UTF-8)
rune 也是 Go 当中的一个类型,并且是 int32 的别名
因为 Unicode 至少占用 2 个字节,所以我们使用 int16 或者 int 类型来表示。如果需要使用到 4 字节,则会加上 \U 前缀;前缀 \u 则总是紧跟着长度为 4 的 16 进制数,前缀 \U 紧跟着长度为 8 的 16 进制数。
前缀 \u 则总是紧跟着长度为 4 的 16 进制数,前缀 \U 紧跟着长度为 8 的 16 进制数。
unicode 包含了一些针对测试字符的非常有用的函数(其中 ch 代表字符):

判断是否为字母:unicode.IsLetter(ch)
判断是否为数字:unicode.IsDigit(ch)
判断是否为空白符号:unicode.IsSpace(ch)

*/

/*
字符串
`This is a raw string \n` 中的 `\n\` 会被原样输出。
和 C/C++ 不一样,Go 中的字符串是根据长度限定,而非特殊字符 \0
string 类型的零值为长度为零的字符串,即空字符串 ""
注意事项 获取字符串中某个字节的地址的行为是非法的,例如:&str[i]
在循环中使用加号 + 拼接字符串并不是最高效的做法,更好的办法是使用函数 strings.Join()(第 4.7.10 节),有没有更好地办法了?有!使用字节缓冲(bytes.Buffer)拼接更加给力(第 7.2.6 节)!
len() 函数:这个内建函数用来获取字符串的ASCII字符个数或字节长度。由于Go语言的字符串都以UTF-8格式保存,每个中文字符可能占用3个字节,因此使用len()获得的是字符串的字节长度,而不是字符数量
utf8.RuneCountInString() 函数:这个函数由UTF-8包提供,用来统计Unicode字符数量。它会正确地计算字符串中的Unicode字符数,无论每个字符占用多少字节
str1 只包含ASCII字符,所以len(str1)和utf8.RuneCountInString(str1)的值是相同的,都是字符串的字符数和字节数。

str2 包含了一个非ASCII字符(日文字符“こん”),这个字符在UTF-8编码中占用3个字节。因此,len(str2)计算的是整个字符串的字节长度,而utf8.RuneCountInString(str2)计算的是字符串中的Unicode字符数,包括多字节的字符。
*/

type ByteSize float64

const (
	Iota          = iota // 通过赋值给空白标识符来忽略值
	KB   ByteSize = 1 << (10 * iota)
	MB
	GB
	TB
	PB
	EB
	ZB
	YB
)

func main() {
	var a int
	var b int32
	a = 15
	// b = a + a    // 编译错误
	b = int32(a + a) //编译成功
	b = b + 5        // 因为 5 是常量,所以可以通过编译
	fmt.Printf("b value is %v \n", b)
	//复数
	var c1 complex64 = 5 + 10i
	fmt.Printf("The value c1 is: %v \n", c1)
	c := complex(11, 22)
	fmt.Printf("The value c is: %v \n", c)
	fmt.Printf("The realc is: %v  imag c is %v\n", real(c), imag(c))
	//位运算
	fmt.Printf("Signed: %d ^ %d = %d\n", 1, -10, 1^-10)
	fmt.Printf("KB %v\n a %v\n", KB, Iota)
	//随机数
	for i := 0; i < 10; i++ {
		r := rand.Int()
		fmt.Printf("%d \n", r)
	}

	for i := 0; i < 10; i++ {
		r := rand.Intn(10)
		fmt.Printf("%d \n", r)
	}
	//设定随机数种子
	timens := int64(time.Now().Nanosecond())
	rand.Seed(timens)
	for i := 0; i < 10; i++ {
		fmt.Printf("%2.2f \n", 100*rand.Float32())
	}

	//字符
	var ch int = '\u0041'
	var ch2 int = '\u03B2'
	var ch3 int = '\U00101234'
	fmt.Printf("%d - %d - %d\n", ch, ch2, ch3) // integer
	fmt.Printf("%c - %c - %c\n", ch, ch2, ch3) // character
	fmt.Printf("%X - %X - %X\n", ch, ch2, ch3) // UTF-8 bytes
	fmt.Printf("%U - %U - %U", ch, ch2, ch3)   // UTF-8 code point
	//字符串
	fmt.Printf("`aa\\n`")

	// 1.1count number of characters: 要注意len统计的是字节,考虑到不同编码字节数的不同,utf8.RuneCountInString能考虑的是ubicode字符数量
	str1 := "asSASA ddd dsjkdsjs dk"
	fmt.Printf("The number of bytes in string str1 is %d\n", len(str1))
	fmt.Printf("The number of characters in string str1 is %d\n", utf8.RuneCountInString(str1))
	str2 := "asSASA ddd dsjkdsjsこん dk"
	fmt.Printf("The number of bytes in string str2 is %d\n", len(str2))
	fmt.Printf("The number of characters in string str2 is %d\n", utf8.RuneCountInString(str2))
	//1.2前缀
	err := strings.HasPrefix(str1, "as")
	print(err, "\n")
	print(strings.Count(str1, "SA"), "\n")
	err = strings.HasSuffix(str2, "dkk")
	print(err, "\n")
	err = strings.Contains(str1, "ddd ")
	print(err, "\n")
	//1.3判断子字符串在父字符串的位置 index
	//染回6
	print(strings.Index(str1, " ddd"), "\n")
	//不存在-1返回
	print(strings.Index(str1, " dddl"), "\n")

	print(strings.Index(str1, "d"), "\n")
	//1.4逆向索引 下标20而不是7
	print(strings.LastIndex(str1, "d"), "\n")
	//1.5如果 ch 是非 ASCII 编码的字符,建议使用以下函数来对字符进行定位:
	r := 'ん'
	print(strings.IndexRune(str2, r), "\n")
	print(strings.Index(str2, string(r)), "\n")
	//1.6替换
	print(strings.Replace(str1, "d", "lin", 2), "\n")
	//1.7重复字符串
	print(strings.Repeat(str1, 2), "\n")
	//修改字符串大小写
	print(strings.ToLower(str1), "\n")
	//修剪字符串
	print(strings.TrimSpace("aaad a "), "kk \n")
	//将开头和结尾在字符集里面的字符去掉
	print(strings.Trim("akkbhuhgkkuk", "akbu"), "\n")
	//分割字符串
	fields := strings.Fields(str1)
	for _, v := range fields {
		print(v, ":")
	}
	print("\n")
	//自定义分割符
	fields = strings.Split("aa,b,121,1", ",")
	for _, v := range fields {
		print(v, ":")
	}
	//拼接 slice 到字符串
	print(strings.Join(fields, "--"), "\n")
	//从字符串中读取内容
	str1Reader := strings.NewReader("hello")
	bytes, _ := io.ReadAll(str1Reader)
	print(string(bytes))
	//Read() 从 [] byte 中读取内容。
	//ReadByte() 和 ReadRune() 从字符串中读取下一个 byte 或者 rune。
	//字符串与其它类型的转换
	var orig string = "666"
	var an int
	var newS string

	fmt.Printf("The size of ints is: %d\n", strconv.IntSize)

	an, _ = strconv.Atoi(orig)
	fmt.Printf("The integer is: %d\n", an)
	an = an + 5
	newS = strconv.Itoa(an)
	fmt.Printf("The new string is: %s\n", newS)

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值