当前位置: 首页 > news >正文

怎么买网站域名震天建设集团网站

怎么买网站域名,震天建设集团网站,网站备案 核验单,网页设计教程书籍推荐类型转换 在 go 语言中#xff0c;类型转换是显式的#xff0c;不会自动转换 go 复制代码 func main(){ i : 100 var f float64 f float64(i) } string 转换成 int 需要借助 strconv 包 使用 strconv.Atoi 函数将 string 转换成 int#xff0c;转换后它会输出两个值类型转换是显式的不会自动转换 go 复制代码 func main(){ i : 100 var f float64 f float64(i) } string 转换成 int 需要借助 strconv 包 使用 strconv.Atoi 函数将 string 转换成 int转换后它会输出两个值 一个是转换后的值一个 error如果转换出错了第一个值是 0 go 复制代码 func main() { str : 100s i, err : strconv.Atoi(str) if err ! nil { fmt.Println(err) } fmt.Println(i) } 这个包还提供了其他的类型的字符串转换方式 strconv.ParseBool将字符串 bool 转换成 bool 类型strconv.ParseFloat将字符串 float 转换成 float 类型strconv.ParseInt将字符串 int 转换成 int 类型strconv.ParseBool将 bool 类型转成 string 类型 数组 go 中数组是定长的也就是说你需要指定数组的长度未初始化的项默认值是 0 数组需要注意一个越界问题也就是说不能访问数组的长度之外的元素 go 复制代码 func main() { // 10 个元素的数组 arr : [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} fmt.Println(arr[9]) // 10 fmt.Println(arr[10]) // 会报错 arr2 : [10]int{1, 2, 3} // 从下标 4 开始到下标 9 的元素都是 0 } 数组的长度是不可改变的 go 复制代码 func main() { arr : [10]int{1, 2, 3, 4, 5, 6, 7, 8, 9, 10} arr [10]int{1, 2, 3} // 数组的长度是不能改变的 } slice slice 是一种动态数组它是由相同类型元素组成的序列 slice 底层由三部分组成 指向底层数组的指针slice 的长度slice 的容量 在底层数组没有被扩展之前slice 的长度和容量相等当我们向 slice 中添加元素时如果超过了 slice 的容量那么 go 就会重新分配一个更大的底层数组并将原始数组复制到心的数组中这个过程被称为扩容 初始化一个 slice 有两种方式 直接使用字面量的方式初始化一个 slice go 复制代码 func main() { s : []int{1, 2, 3, 4} } 使用 make 函数创建一个 slice它接收三个参数 第一个参数是类型第二个参数是长度第三个参数是容量 第三个参数可以省略也就是说如果不指定容量那么容量等于长度 go 复制代码 func main() { s : make([]int, 3, 5) // 创建一个长度为 3容量为 5 的切片 } slice 的访问方式和数组一样 通过下标访问 go 复制代码 arr : [4]int{1, 2, 3, 4} fmt.Println(arr[0]) // 1 s : []int{1, 2, 3, 4} fmt.Println(s[0]) // 1 通过区间访问前闭后开 go 复制代码 arr : [4]int{1, 2, 3, 4} fmt.Println(arr[0:2]) // 1,2 s : []int{1, 2, 3, 4} fmt.Println(s[0:2]) // 1,2 区间访问的时候如果省略了开始的下标那么默认是 0如果省略了结束的下标那么默认是 slice 的长度 不能越界访问 删除 slice 中的某项元素可以使用 append 函数三个点是展开操作符它会将 s 中的元素展开 go 复制代码 s : []int{1, 2, 3, 4, 5, 6, 7, 8} s append(s[:1], s[2:]...) 数组和 slice 最大的区别是数组的长度是固定的而 slice 的长度是可变的 go 复制代码 arr : [8]int{1, 2, 3, 4, 5, 6, 7, 8} // 数组 s : []int{1, 2, 3, 4, 5, 6, 7, 8} // 切片 数组可以转变成切片 go 复制代码 arr : [8]int{1, 2, 3, 4, 5, 6, 7, 8} // 数组 s : arr[:] // 将数组转换成切片 slice 是引用类型 如果一个函数接收的是切片那么它接收的是切片的引用也就是说它会改变原始切片的值 go 复制代码 func main() { s : []int{1, 2, 3, 4, 5, 6, 7, 8} fmt.Println(s) // [1 2 3 4 5 6 7 8] addOne(s) fmt.Println(s) // [2 3 4 5 6 7 8 9] } // 接收的事切片的引用 func addOne(n []int) { for i : 0; i len(n); i { n[i] n[i] 1 } } 如果函数接收的是数组那么它接收的是数组的值也就是说它不会改变原始数组的值 go 复制代码 func main() { s : [8]int{1, 2, 3, 4, 5, 6, 7, 8} fmt.Println(s) // [1 2 3 4 5 6 7 8] addOne(s) fmt.Println(s) // [1 2 3 4 5 6 7 8] } func addOne(n [8]int) { for i : 0; i len(n); i { n[i] n[i] 1 } } 那么数组要实现引用传递怎么办呢可以使用指针 go 复制代码 func main() { s : [8]int{1, 2, 3, 4, 5, 6, 7, 8} fmt.Println(s) // [1 2 3 4 5 6 7 8] addOne(s) fmt.Println(s) // [2 3 4 5 6 7 8 9] } func addOne(n *[8]int) { for i : 0; i len(n); i { n[i] n[i] 1 } } 最后slice 如何传递指针在函数内部需要使用 * 来解引用然后在对 slice 进行操作 go 复制代码 func main() { s : []int{1, 2, 3, 4, 5, 6, 7, 8} fmt.Println(s) addOne(s) fmt.Println(s) } func addOne(n *[]int) { // 先对 n 解引用 _n : *n for i : 0; i len(_n); i { _n[i] _n[i] 1 } } map map 未初始化可以取值但赋值会报错 go 复制代码 func main() { var m1 map[string]int fmt.Println(m1[age]) // 0 m1[age] 1 // 报错 } map 的初始化有两种方式 go 复制代码 m1 : map[string]int{age: 1} // 字面量的方式 m2 : map[string]int{} // 这种也是字面量 m3 : make(map[string]int) // 使用 make 函数 如何判断一个属性在不在 map 中呢可以使用 ok 来判断 go 复制代码 func main() { m2 : make(map[string]int) m2[age] 25 a, ok : m2[age] fmt.Println(a, ok) // 25 true a, ok m2[age2] fmt.Println(a, ok) // 0 false } switch go 中的 switch 如果命中某条 case 语句后就不会命中其他 case 语句了 switch 可以使用 x.(type) 的方式类判断一个变量的类型x.(type) 只能在 switch 语句中使用不能在 if 语句中使用 go 复制代码 func typeof(x interface{}) { switch x.(type) { case int: fmt.Println(int) case string: fmt.Println(string) default: fmt.Println(unknown) } } for 在 for 循环中如果操作指针的话会有一个问题如下所示添加到 oddNumbers 中都是 7 因为 number 是一个变量它的地址是不变的所以 oddNumbers 中的元素都是 number 的地址而 number 最后的值是 7 go 复制代码 func main() { numbers : []int{1, 2, 3, 4, 5, 6, 7} var oddNumbers []*int for _, number : range numbers { // number 的地址是不变的 oddNumbers append(oddNumbers, number) } for _, oddNumber : range oddNumbers { fmt.Println(*oddNumber) } } 如何解决这个问题呢可以使用一个临时变量每一个循环进来的时候都创建一个临时变量然后将它的地址添加到 oddNumbers 中 go 复制代码 func main() { numbers : []int{1, 2, 3, 4, 5, 6, 7} var oddNumbers []*int for _, number : range numbers { // 每次循环都会创建一个新变量然后将它的地址添加到 oddNumbers 中 tmp : number oddNumbers append(oddNumbers, tmp) } for _, oddNumber : range oddNumbers { fmt.Println(*oddNumber) } } error 任何一个实现了 Error() 方法的类型都可以作为错误类型 go 复制代码 type MyError struct { message string code int } func (e MyError) Error() string { return e.message } func add() (*int, error) { var myError MyError{ message: This is an error, code: 500, } return nil, myError // 使用自定义的错误 } 判断一个 error 是什么类型最好使用 errors.Is 函数不要用 来判断 go 复制代码 e1 : fmt.Errorf(error 1: %w, io.EOF) fmt.Println(errors.Is(e1, io.EOF)) // true fmt.Println(e1 io.EOF) // false error 类型断言可以使用 errors.As 函数不要使用 err.(xx) 因为 errors.As 和 errors.Is 函数是可以判断包装过的 error package 在一个 package 中执行顺序 先执行 const 常量再执行 var 变量然后再执行 init 函数最后执行 main 函数 如果有引入其他的 package那么它会先执行其他的 package 的 constvarinit然后再执行当前 package 的 constvarinit这是一个深度优先的顺序 go mod 是一个用于管理 go 的依赖模块它会将依赖的模块下载到 go 的缓存目录中然后在 go.mod 文件中记录下来一般存储在 $GOPATH/pkg/mod 目录中 go mod 的命令 go mod init初始化一个 go.mod 文件go mod tidy根据 go.mod 文件整理依赖go mod download下载 go.mod 文件中的依赖但不安装go mod verify验证依赖是否正确和完整go mod graph以图形化显示模块之间的依赖关系go mod why解释模块为什么需要特定的依赖 receiver 指针类型 receiver 使用指向该类型的指针作为接收者值类型 receiver 使用该类型的值作为接收者 定义一个 Animal 接口它有一个 Eat 方法定义 Dog 结构体它有一个 Say 方法然后实现 Animal 接口 使用指针类型作为 receiver实现接口需要使用指针类型的值 go 复制代码 type Animal interface { Eat() } type Dog struct { Name string } func (d *Dog) Say() { fmt.Printf(Name is %v, d.Name) } func main() { // 这里只能使用指针类型的值 var a Animal Dog{Name: uccs} a.Say() } 使用值类型作为 receiver实现接口可以使用值类型的值也可以使用指针类型的值 go 复制代码 type Animal interface { Say() } type Dog struct { Name string } func (d Dog) Say() { fmt.Printf(Name is %v, d.Name) } func main() { // 这里可以使用指针类型的值 var a Animal Dog{Name: uccs} a.Say() // 也可以使用值类型的值 var a1 Animal Dog{Name: astak} a1.Say() } interface 接口类型断言 go 复制代码 func AnimalSleep(e Eater){ if s, ok : e.(Animal); ok { s.Sleep() } } 对于 interface 类型的变量不能使用指针类型的零值(指针类型的零值是 nil)你会处理 go 中的 nil 吗 抽象接口的实现 go 复制代码 type Worker interface { doWork() Start() } type BaseWorker struct { Worker } func (b *BaseWorker) Start() { fmt.Println(start) b.doWork() fmt.Println(end) } type NormalWorker struct { BaseWorker } func (n *NormalWorker) doWork() { fmt.Println(do work) } func NewNormalWorker() Worker { n : NormalWorker{BaseWorker{}} // 这边需要赋值不然会报错 n.Worker n return n } func main() { NewNormalWorker().Start() } goroutine 中的竞态 当有多个 goroutine 对同一个变量进行读写操作时就会出现竞态 因为写入一个变量的操作不是原子的一般会分为三步 读取变量的值read counter对变量的值进行操作counter counter 1将最新的值写入变量write counter go 复制代码 var counter int32 func main() { var wg sync.WaitGroup for i : 0; i 1000; i { wg.Add(1) go func(i int) { counter counter 1 wg.Done() }(i) } wg.Wait() fmt.Println(counter) // 不一定是 1000 } 如何解决这个问题呢 使用 atomic 包中的原子操作 在 x86 架构中atomic.AddInt32 函数使用 lock xaddq 指令来实现原子加操作 go 复制代码 var counter int32 func main() { var wg sync.WaitGroup for i : 0; i 1000; i { wg.Add(1) go func(i int) { // 这个操作是原子的 atomic.AddInt32(counter, 1) wg.Done() }(i) } wg.Wait() fmt.Println(counter) } 这两种方法是一样的只是 atomic.AddInt32 的方法更加简洁 go 复制代码 var counter atomic.Int32{} func main() { var wg sync.WaitGroup for i : 0; i 1000; i { wg.Add(1) go func(i int) { counter.Add(1) wg.Done() }(i) } wg.Wait() fmt.Println(counter.Load()) } atomic.CompareAndSwapInt64 函数是使用 CPU 的原子指令来实现的它使用了 CPU 提供的 compare-and-swap 指令来保证原子性 CAS 指令可以原子的比较并交换一个内存地址中的值它有三个操作数内存地址 addr期望的旧值 old新值 new如果内存地址 addr 中的值等于 old那么将 new 的值写入 addr 中否则不做任何操作 go 复制代码 var counter int32 func main() { var wg sync.WaitGroup for i : 0; i 1000; i { wg.Add(1) go func(i int) { for { if swaped : atomic.CompareAndSwapInt32(counter, counter, counter1); swaped { break } } wg.Done() }(i) } wg.Wait() fmt.Println(counter) } 使用锁 go 复制代码 var counter int32 var lock sync.Mutex func main() { var wg sync.WaitGroup for i : 0; i 1000; i { wg.Add(1) go func(i int) { lock.Lock() counter counter 1 lock.Unlock() wg.Done() }(i) } wg.Wait() fmt.Println(counter) }
http://www.pierceye.com/news/600159/

相关文章:

  • 广州公司网站建设设计顾视频网站的建设预算
  • 商务网站规划与网页制作seo优化内容
  • 石家庄网站定做公众号开发单位
  • 做预定网站的作用网站建设需求方案文档
  • 西安网站建设高端万网总裁张向东
  • 肖鸿昌建筑网站广州网站建设设计公司信息
  • 网站建设 大公司好成都网站建设哪家售后好
  • 外贸网站模板制作微营销推广方案
  • 网站开发体系用node.js可以做网站吗
  • 一个vps建两个网站怎么弄数据库网络营销应用方式
  • 网站开发快递c 网站开发入门视频教程
  • 阿里巴巴国际站介绍深圳网站建设 猴王网络
  • 扬中网站建设哪家好五百丁简历官网
  • 素马设计顾问讲解价格短视频seo什么意思
  • 注册域名查询网站智慧团建网站登陆平台
  • 网站建设和搜索引擎优化技术有哪些
  • 网站创建的基本流程seo网站排名全选
  • 乐山网站公众号建设wordpress微电影模板
  • 天津专门做网站长春市网站制作
  • 怎样用php做网站英文网站建设580
  • 凡客登录入口网站优化垂直化好还是扁平化好
  • 网站诊断高端网站建设 杭州
  • 营销网站案例北京公司建设网站
  • 网站建设全域云网店美工的职责有哪些
  • seo优化网站的手段亚洲国产中文域名查询
  • 网络营销网站源码学校网站建设评审会议通知
  • 品牌网站升级创意设计椅子
  • 海口网站制作公司商标注册网上查询
  • 世界上前端做的最好的网站2345浏览器官网网址
  • 做模板网站赚钱吗网站建设需要多少内存