
编程开发
切片copy
当我们需要在Go语言中复制一个切片时,我们可以使用内置的copy函数。copy函数可以将一个切片的元素复制到另一个切片中。下面是一个示例: 在上面的示例中,我们首先创建了一个源切片
bool byte complex64 complex128 error float32 float64 int int8 int16 int32 int64 rune string uint uint8 uint16 uint32 uint64 uintptr变量来源于数学,是计算机语言中能储存计算结果或能表示值抽象概念。变量可以通过变量名访问。Go 语言变量名由字母、数字、下划线组成,其中首个字符不能为数字。申明变量的一般形式是使用var关键字:
var identifier type一次可以申明多个变量:
var identifier1, identifier2 type例如:
package main
import "fmt"
// 吴老二 个人博客地址 http://www.wulaoer.org
func main() {
var a string = "Go"
fmt.Println(a)
var b, c int = 1, 2
fmt.Println(b, c)
}
结果:
Go 1 2
package main
import "fmt"
// 吴老二 个人博客地址 http://www.wulaoer.org
var a string = "Golang"
func main() {
var a string = "Go"
fmt.Println(a)
var b, c int = 1, 2
fmt.Println(b, c)
}
这里定义了两个变量,一个局部变量(Go),一个全局变量(Golang),如果直接执行程序一定打印的是Go,因为是局部变量,如果把局部变量注释掉会打印什么,可以试试看。
var v_name v_type v_name = value零值就是变量没有初始化时系统默认设置的值。
package main
import "fmt"
// 吴老二 个人博客地址 http://www.wulaoer.org
func main() {
var a = "Golang" //申明的变量进行了初始化
fmt.Println(a)
var b int //申明的变量没有初始化
fmt.Println(b)
var c bool //申明布尔值的变量没有初始化默认为false
fmt.Println(c)
}
结果:
Golang 0 false根据不同的数据类型初始化值不一样,一下总结了一些:
* 数值类型(包括complex64/128)为 0 * 布尔类型为 false * 字符串为 ""(空字符串)以下几种类型为 nil:
var a *int var a []int var a map[string] int var a chan int var a func(string) int var a error // error 是接口2、根据变量自行判定变量类型。
package main
import "fmt"
// 吴老二 个人博客地址 http://www.wulaoer.org
func main() {
var d = true //值是什么类型就定义的什么类型
fmt.Println(d)
}
结果:
true3、省略 var, 注意 := 左侧如果没有声明新的变量,就产生编译错误,格式:
v_name := value举例:
var a int // 吴老二 个人博客地址 http://www.wulaoer.org a :=1 // 这时候会产生编译错误,因为前面初始化了a,a :=1就等于var a = 1 正确的方式是: a := 1 //不需要前面的var a int多个变量可以这样写:
a,b,c := 1,2,3 // 此时不会产生编译错误,因为有声明新的变量,因为 := 是一个声明语句,相当于a,b,c = 1,2,3,而不是a=1,b=2,c=3举例:
package main
import "fmt"
// 吴老二 个人博客地址 http://www.wulaoer.org
func main() {
a,b := 1,"hello"
fmt.Println(a)
}
就会报错
a declared and not used如果输出两个变量
fmt.Println(a,b)结果为:
1 24、多变量声明
//类型相同多个变量, 非全局变量
var vname1, vname2, vname3 type
vname1, vname2, vname3 = v1, v2, v3
// 吴老二 个人博客地址 http://www.wulaoer.org
var vname1, vname2, vname3 = v1, v2, v3 // 和 python 很像,不需要显示声明类型,自动推断
vname1, vname2, vname3 := v1, v2, v3 // 出现在 := 左侧的变量不应该是已经被声明过的,否则会导致编译错误
// 这种因式分解关键字的写法一般用于声明全局变量
var (
vname1 v_type1
vname2 v_type2
)
举例:
package main
// 吴老二 个人博客地址 http://www.wulaoer.org
var x, y int
var ( // 这种因式分解关键字的写法一般用于声明全局变量
a int
b bool
)
var c, d int = 1, 2
var e, f = 123, "hello"
//这种不带声明格式的只能在函数体中出现
//g, h := 123, "hello"
func main(){
g, h := 123, "hello"
println(x, y, a, b, c, d, e, f, g, h)
}
以上实例执行结果为:
0 0 0 false 1 2 123 hello 123 hello
当使用等号 = 将一个变量的值赋值给另一个变量时,如:j = i,实际上是在内存中将 i 的值进行了拷贝:
你可以通过 &i 来获取变量 i 的内存地址,例如:0xf840000040(每次的地址都可能不一样)。值类型的变量的值存储在栈中。
内存地址会根据机器的不同而有所不同,甚至相同的程序在不同的机器上执行后也会有不同的内存地址。因为每台机器可能有不同的存储器布局,并且位置分配也可能不同。
更复杂的数据通常会需要使用多个字,这些数据一般使用引用类型保存。
一个引用类型的变量 r1 存储的是 r1 的值所在的内存地址(数字),或内存地址中第一个字所在的位置。
这个内存地址为称之为指针,这个指针实际上也被存在另外的某一个字中。
同一个引用类型的指针指向的多个字可以是在连续的内存地址中(内存布局是连续的),这也是计算效率最高的一种存储形式;也可以将这些字分散存放在内存中,每个字都指示了下一个字所在的内存地址。
当使用赋值语句 r2 = r1 时,只有引用(地址)被复制。
如果 r1 的值被改变了,那么这个值的所有引用都会指向被修改后的内容,在这个例子中,r2 也会受到影响。
package main
import "fmt"
// 吴老二 个人博客地址 http://www.wulaoer.org
func main() {
var a string = "abc"
fmt.Println("hello, world")
}
尝试编译这段代码将得到错误 a declared and not used。此外,单纯地给 a 赋值也是不够的,这个值必须被使用,所以使用
fmt.Println("hello, world", a)
会移除错误。但是全局变量是允许声明但不使用。 同一类型的多个变量可以声明在同一行,如:
var a, b, c int多变量可以在同一行进行赋值,如:
var a, b int var c string a, b, c = 5, 7, "abc"上面这行假设了变量 a,b 和 c 都已经被声明,否则的话应该这样使用:
a, b, c := 5, 7, "abc"
const identifier [type] = value这里可以省略类型[type],因为编译器会根据变量的值来推断变量类型。
* 显示类型: const b string = "abc" * 隐藏类型: const b = "abc"如果有多个相同类型的声明可以简写成:
const c_name1, c_name2, c_name3 = value1, value2, value3下面举例说明一下:
package main
import "fmt"
// 吴老二 个人博客地址 http://www.wulaoer.org
func main() {
const LENGTE int = 30 //声明变量LENGTE,相当于const LENGTE = 30
const WIDTH int = 5 //声明变量WIDTH,相当于const WIDTH = 5
var area int //声明area的数据类型,如果这里不声明变量,后面就是不能使用
const a,b,c = 1,false,"str" //多重赋值
area = LENGTE * WIDTH //变量运算得到一个全新的变量
fmt.Printf("面积: %d",area) //打印运算后得到的变量
println() //打印空行,进行分割
println(a,b,c) //打印定义的多重变量
}
打印结果:
面积: 150 1 false str也可以使用常量做枚举:
package main
import "unsafe"
// 吴老二 个人博客地址 http://www.wulaoer.org
const (
a = "wolf27w"
b = len(a) //计算长度
c = unsafe.Sizeof(a) //unsafe.Sizeof()计算表达式的值
)
func main() {
println(a,b,c) //这里没有导入fmt函数,所以可以直接使用println打印
}
打印结果:
wolf27w 7 16
const ( a = iota b = iota c = iota )第一行a=iota,a的值就是0,新增一行b的值就自动加1等于2,c就等于3,形式如下:
package main
import “fmt”
// 吴老二 个人博客地址 http://www.wulaoer.org
func main() {
const (
a = iota //第一行值为0
b //自动加1
c //自动加1
d = "ha" //申明的独立值
e // "ha" ioya += 1
f = 100 //iota += 1
g //100 iota += 1
h = iota //7 恢复计数
i //8
)
fmt.Println(a,b,c,d,e,f,g,h,i)
}
打印结果:
0 1 2 ha ha 100 100 7 8下面看一下例子:
package main
import "fmt"
// 吴老二 个人博客地址 http://www.wulaoer.org
const (
i=2<<iota //表示二进制左移1位,010
j=3<<iota //表示二进制左移2位,110
k //表示二进制左移3位,1100
l //表示二进制左移4位,11000
)
func main() {
fmt.Println("i=",i)
fmt.Println("j=",j)
fmt.Println("k=",k)
fmt.Println("l=",l)
}
打印结果:
i= 1 j= 6 k= 12 l= 24注释:iota 表示从 0 开始自动加 1,所以 i=1<<0, j=3<<1(<< 表示左移的意思),即:i=1, j=6,这没问题,关键在 k 和 l,从输出结果看 k=3<<2,l=3<<3。 简单表述:
* i=1:左移 0 位,不变仍为 1; * j=3:左移 1 位,变为二进制 110, 即 6; * k=3:左移 2 位,变为二进制 1100, 即 12; * l=3:左移 3 位,变为二进制 11000,即 24。以上就是对Golang的诠释,有部分参考了菜鸟教程,很多东西需要沉淀一下,不是画完了就完事了,下个章节就是Golang的判断和循环了,算是真正进去Golang的学习。
评论 0