Go 语言基础语法-下
函数
package main
import "fmt"
func add(a int, b int) int {
return a + b
}
func add2(a, b int) int {
return a + b
}
func exists(m map[string]string, k string) (v string, ok bool) {
v, ok = m[k]
return v, ok
}
func main() {
res := add(1, 2)
fmt.Println(res) // 3
v, ok := exists(map[string]string{"a": "A"}, "a")
fmt.Println(v, ok)
}
- 需要注意,golang 一大特点就是 变量类型后置,变量名在前 。体现在函数的创建也是一样,先写函数名,然后紧跟着是括号里传参,完了之后才把函数的返回值类型加上,如果不加的话 golang 默认是无返回值,只进行函数体里的操作,比较省事儿。
- 可以看代码里的
exists函数,返回值类型是(v string, ok bool),这和我们之前学的很不一样,着重解释一下 :意思是 exists 函数的返回值有两个,第一个是 string 类型的,第二个是bool 类型的。第一个就是我们平时都用的需要的返回值,第二个 bool 类型的值通常作为返回目标是否存在的标志。
指针
相比于 C/C++ 里的指针,golang 里的指针作用非常有限,指针的一个主要用途就是对传入的参数进行修改 。学过 C 语言的指针就会知道,我们传一个参数到函数里,传的是这个参数的值,相当于是复制过去的,在另一个函数里对它进行修改对这个参数本身并没有影响,所以加上指针之后,就变成了传引用,将参数在内存的地址传过去,那么此时再进行修改,参数的值就会改变了。
可以参考示例代码:
package main
import "fmt"
func add2(n int) {
n += 2
}
func add2ptr(n *int) {
*n += 2
}
func main() {
n := 5
add2(n)
fmt.Println(n) // 5
add2ptr(&n)
fmt.Println(n) // 7
}
ps : 还要注意传引用的时候要有取地址符 &
结构体
type user struct {
name string
password string
}
func checkPassword(u user, password string) bool {
return u.password == password
}
func checkPassword2(u *user, password string) bool {
return u.password == password
}
func main() {
a := user{name: "wang", password: "1024"}
b := user{"wang", "1024"}
c := user{name: "wang"}
c.password = "1024"
var d user
d.name = "wang"
d.password = "1024"
fmt.Println(a, b, c, d) // {wang 1024} {wang 1024} {wang 1024} {wang 1024}
fmt.Println(checkPassword(a, "haha")) // false
fmt.Println(checkPassword2(&a, "haha")) // false
}
- 和 C 语言一样的结构体。初始化有不同的方式,如果初始化的时候显式地加上了字段的名称的话,那么就可以不完全赋值,比如a是给每个字段都赋值了,而c就只给部分赋值了,对于未初始化的默认给初值 0,字符串就是空串;如果是隐式的,那么就如 b 一样了。
- 如代码中的 d,可以用
.来使用结构体的值,这对于学过 C 语言的同学来说肯定是不陌生的 - 作为参数传入时 ,肯定是也区分带星号不带星号(就是用不用指针的意思)。那么不带星号就是修改参数的值不对本体有影响。
结构体方法
type user struct {
name string
password string
}
func (u user) checkPassword(password string) bool {
return u.password == password
}
func (u *user) resetPassword(password string) {
u.password = password
}
func main() {
a := user{
name: "wang",
password: "1024",
}
a.resetPassword("2048")
fmt.Println(a.checkPassword("2048")) // true
}
- 参考上一part 的结构体,结构体方法其实就是把本来在参数列表里的结构体变量往前提,提到函数名前边,这样做的好处我们可以看倒数第二行
a.resetPassword("2048"),我们就可以通过变量名.方法名的方式来调用函数了。
字符串操作
字符串常用操作
介绍了一些常用的golang 处理字符串的方法
func main() {
a := "hello"
// 判断前一个字符串里是否有后一个字符串
fmt.Println(strings.Contains(a, "ll")) // true
// 字符串基数
fmt.Println(strings.Count(a, "l")) // 2
fmt.Println(strings.HasPrefix(a, "he")) // true
fmt.Println(strings.HasSuffix(a, "llo")) // true
// 查找某个字符串的位置
fmt.Println(strings.Index(a, "ll")) // 2
// 连接多个字符串
fmt.Println(strings.Join([]string{"he", "llo"}, "-")) // he-llo
// 重复多个字符串
fmt.Println(strings.Repeat(a, 2)) // hellohello
fmt.Println(strings.Replace(a, "e", "E", -1)) //hEllo
fmt.Println(strings.Split("a-b-c", "-")) // [a b c]
fmt.Println(strings.ToLower(a)) // hello
fmt.Println(strings.ToUpper(a)) // HELLO
fmt.Println(len(a)) // 5
}
字符串的格式化
使用 fmt.Printf() 方法进行格式化输出,和 C/C++ 的 printf() 及 java 的 String.format() 基本一样用法。
- 不过需要区别且 体现Go 语言的简洁性的一大特点 在于:无论什么数据类型,都可以用
%v来输出,不像C 语言里边 %c 代表字符型、%d 代表整型什么什么的,一个%v就是万能的。 - 如果想要更详细的输出信息,可以使用
%+v和%#v,后者比前者更详细,这里就不过多演示。
JSON处理
- 很简单,对于一个已有的结构体,保证每个字段的首字母都大写 (也就是表示在 golang里这属于公开字段了),就可以用
json.Marshal()方法去事例化,这样就会变成一个数组(全是16进制数字),打印的时候强制转换类型为 string 就能打印出字符串了。