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

【Go】C++ 转 Go 第(二)天:变量、常量、函数与init函数

本专栏文章持续更新,新增内容使用蓝色表示。

食用指南

本文适合有 C++ 基础的朋友,想要快速上手 Go 语言。可直接复制代码在 IDE 中查看,代码中包含详细注释和注意事项。

Go 的环境搭建请参考以下文章:

【Go】C++ 转 Go 第(一)天:环境搭建 Windows + VSCode 远程连接 Linux -CSDN博客

变量声明与使用

Go 语言对变量的要求非常严格,float32 和 float64 是不同的类型,且没有自动类型转换机制。

C++ vs Go 变量声明对比

特性C++Go
类型声明int a = 5;var a int = 5
类型推导auto b = "hello"; (C++14+)b := "hello"
多变量声明int x=1, y=2;x, y := 1, 2
默认值未初始化是未定义行为自动零值初始化

注意事项:

Go 中没有 char 类型,使用 byte(ASCII) 和 rune(Unicode)。

变量声明后必须使用,否则编译报错。

:=简短声明只能在函数内部使用。

var.go 

// 声明变量
package mainimport ("fmt"
)// 二、全局变量声明
var e int
var f float64 = 9
var g = "q"// var h:=1		// := 只能用在函数体内使用func main() {// 一、局部变量声明// 默认值是0var a intfmt.Println("a =", a)// go 中没有 char 字符类型,但是有byte (ASCII) / rune (Unicode)// 带初始化值var b int = 8fmt.Println("b =", b)// 自动匹配,相当于auto// 1. varvar c = "var c"// 使用类型推导可以使用 %v 占位符fmt.Printf("c = %v \t", c)    // 非格式化输出,带换行符fmt.Printf("type : %T \n", c) // 格式化输出// 2. :=d := 5.5fmt.Printf("d = %v \t", d)fmt.Printf("type : %T \n", d)fmt.Println("e =", e)fmt.Println("f =", f)fmt.Println("g =", g)// fmt.Println("h =", h)// 三、多个变量声明// 1. 单行// 1) 同一种数据类型var a1, a2 int = 56, 78fmt.Println("a1 =", a1, ",", "a2 =", a2)// 2) 不同数据类型(自动匹配)var b1, b2 = "hello", 8.9fmt.Printf("b1 = %v \t", b1)fmt.Printf("type : %T \n", b1)fmt.Printf("b2 = %v \t", b2)fmt.Printf("type : %T \n", b2)// 2. 多行var (c1 int  = 1c2 bool = false)fmt.Println("c1 =", c1, ",", "c2 =", c2)}

执行结果

常量与iota枚举

iota 是 Go 语言的常量计数器,只能在 const 内部使用。

iota 特性

每遇到一个 const 关键字,iota 重置为0

const 声明块中每新增一行,iota 自增1

支持在表达式中使用 iota

const.go 

package mainimport ("fmt"
)// 二、const 定义枚举类型
const (apple  = 0banana = 1
)// 可在 const 中添加关键字 iota(只能在const内部使用),第一行的 iota 的默认值是0,之后每行 iota 加1。
// 读法: i o ta
const (_         = iota // 跳过 0monday           // 1tuesday          // 2wednesday        // 3
)const (cat   = iota * 2 // 0 * 2dog              // 1 * 2panda            // 2 * 2
)const (a, b   = iota + 1, iota + 2 // iota = 0, a = iota + 1 = 1, b = iota + 2 = 2a1, b1                      // iota = 1, a1 = iota + 1 = 2, b1 = iota + 2 = 3a2, b2                      // iota = 2, a2 = iota + 1 = 3, b2 = iota + 2 = 4c, d = iota * 2, iota * 3 // iota = 3, c = iota * 2 = 6, d = iota * 3 = 9c1, d1c2, d2
)func main() {// 一、常量const x string = "xian"fmt.Println("x =", x)// x = "xining"	// 只读fmt.Printf("apple=%d, banana=%d \n", apple, banana)fmt.Printf("monday=%d, tuesday=%d, wednesday=%d\n", monday, tuesday, wednesday)fmt.Printf("cat=%d, dog=%d, panda=%d\n\n", cat, dog, panda)fmt.Printf("a=%d, b=%d \n", a, b)fmt.Printf("a1=%d, b1=%d \n", a1, b1)fmt.Printf("a2=%d, b2=%d \n\n", a2, b2)fmt.Printf("c=%d, d=%d \n", c, d)fmt.Printf("c1=%d, d1=%d \n", c1, d1)fmt.Printf("c2=%d, d2=%d \n", c2, d2)
}

执行结果

函数

特性

  • 参数顺序为参数名在前,类型在后。

  • Go 的返回值中没有 void,不需要返回值时直接省略返回类型。

  • Go 语言支持多返回值。

  • Go 中只有值传递,但可以传递指针来修改原值。

func.go 

package mainimport "fmt"// 形参的变量名和类型和C++的相反,末尾的是返回值类型。没有返回值,末尾可以不写
// 注意:go中没有void关键字,不需要返回值时直接省略// go中只有值传递,但是传递的值不同,结果也不同// 一、返回单个匿名返回值
func test(a int, b int) bool {fmt.Println("-------test-------")fmt.Println("a =", a, "b =", b)c := truereturn c
}// 二、返回多个匿名返回值
func test1(a int, b string) (int, string) {fmt.Println("-------test1------")fmt.Println("a =", a, "b =", b)return a, b
}// 三、返回多个有名返回值
// 1. 多个返回值类型不同
func test2(a int, b string) (e float64, f string) {fmt.Println("-------test2------")fmt.Println("a =", a, "b =", b)// 这两个变量也属于函数形参,在未赋值之前使用不会报错,前者默认为0,后者默认为空// 防止不可控的野指针、野地址的出现fmt.Println("e =", e, "f =", f)// go没有隐式类型转换,比如将float64改为float32或者int都会报错e = 17.3f = "world"return
}// 2. 多个返回值类型相同
func test3(a int, b string) (e, f int) {fmt.Println("-------test3------")fmt.Println("a =", a, "b =", b)return 6, 7
}// 传递指针,函数内更改会影响原来的值
func change(n *int) {*n = 99
}func main() {c := test(1, 2)// 注意go中定义的变量必须要使用,否则会报错fmt.Println("c =", c)// 多返回值时, 可以使用下划线 _ 忽略不需要的返回值_, d := test1(3, "hello")fmt.Println("d =", d)e, f := test2(4, "world")fmt.Println("e =", e, "f =", f)e1, f1 := test3(5, "word")fmt.Println("e1 =", e1, "f1 =", f1)fmt.Println("\n======传指针=======")// 使用时传地址num := 7fmt.Println("未调用之前:", num)change(&num)fmt.Println("调用之后:", num)}

执行结果

init 函数与包导入

目录结构如下所示:

导入方式说明

  1. 标准导入:通过包名调用导出函数

  2. 匿名导入:只执行包的init函数,不直接使用包中其他函数

  3. 别名导入:为长包名设置简短别名

  4. 导入点:将包中全部方法导入当前作用域(谨慎使用)

lib1/lib1.go

package lib1import "fmt"func init() {fmt.Println("-----lib1.init()-----")
}// lib1包提供的API
// 以下函数名大写表示对外开放
// 小写则表示当前函数只能再包内调用
func Lib1Test() {fmt.Println("-----lib1Test()-----")
}

lib2/lib2.go

package lib2import "fmt"func init() {fmt.Println("-----lib2.init()-----")
}// lib2包提供的API
// 以下函数名大写表示对外开放
// 小写则表示当前函数只能再包内调用
func Lib2Test() {fmt.Println("-----lib2Test()-----")
}

main.go

package main// 暂时采用这种写法
// 导包时会调用对应的 init 函数
import (// 从 GOPATH 开始的相对路径// 1. 标准导入"GoLangStudy/5_initStudy/lib1""GoLangStudy/5_initStudy/lib2"// 2. 匿名导入(_+空格)// go 对语法要求严格,导包不使用,会报错// 如果只执行包的 init() 函数,不直接使用包中的其他函数,可通过匿名导包实现//_ "GoLangStudy/5_initStudy/lib2"// 3. 别名导入// 包名很长的时候可以使用// mylib2 "GoLangStudy/5_initStudy/lib2"// 4. 导入点(谨慎使用)// 将包中的全部方法导到当前包的作用域中,可直接调用API// 不同包可能会出现同名函数,不推荐生产上使用// . "GoLangStudy/5_initStudy/lib2"
)func main() {// 1. 通过导包,可以调用 lib1 的函数。lib1.Lib1Test()lib2.Lib2Test()// 3. 别名调用方式// mylib2.Lib2Test()// 4. 导入点// Lib2Test()
}

执行结果


如有问题或建议,欢迎在评论区中留言~

http://www.dtcms.com/a/504296.html

相关文章:

  • 网站获取访客专业网站建设培训机构
  • 专业做互联网招聘的网站新东方研学网站那家公司做的
  • Java异步编程难题拆解
  • Map<String, Object> - 餐厅的“菜单“
  • 宁波网站建设流程有哪些网站设计考虑要素
  • 新手学做免费网站西安 网站搭建
  • floodfill 算法(dfs)
  • node做网站岳阳做网站推荐
  • 成都营销型网站建设公司网站设计中新闻版块怎么做
  • 基于LM2904A(3PEAK)的5V~24V电源电压检测电路完整设计笔记
  • 如何获取PyTorch中间层的值:两种实用方法详解
  • 电容式传感器
  • 网络授时与授时概念解析
  • 设计师投稿网站自媒体平台大全
  • 计算机网站怎么做wordpress 软件价格
  • Linux中I2C常见问题二
  • 做泰迪狗网站的意义下载全网搜
  • linux 5.10 移植kfence调试踩内存纪要
  • 网站游戏网站建设动漫设计与制作主要学什么
  • [嵌入式系统-146]:五次工业革命对应的机器人形态的演进、主要功能的演进以及操作系统的演进
  • 网站开发工程师前景分析网站推广经验杂谈
  • 做网站行业统称叫什么行业那些网站可以做0首付分期手机号
  • 百度网址大全 官网首页seoul是什么国家
  • 山西忻州市忻府区怎么把做的网站优化到百度
  • Shell脚本入门:从基础到实战
  • 【Linux】深入理解线程同步与互斥
  • 山东青岛网站建设公司排名网站空白页黑链
  • C++学习之变量、常量、关键字、标识符命名规则、数据类型
  • BMS电池管理系统学习笔记_SOC算法
  • 浅谈信创数据库改造重难点