您好,欢迎来到微智科技网。
搜索
您的当前位置:首页Go语言入门(变量、函数和指针)

Go语言入门(变量、函数和指针)

来源:微智科技网
go是一门很特别的语言,有以下特征:
  • 没有“对象”,没有继承多态,没有泛型,没有try/catch
  • 有接口,函数式编程,CSP并发模型(goroutine + channel)
  • 语法简单

我在网上看到有人说,go语言学习很简单啊,比js还简单。啊?这个比喻也是激励我来学习go的,我想看看多简单!!!

开发环境

废话不多说,赶紧把go开发的环境搭起来才可以愉快的撸代码啊。

1. 安装

gopath 和 goroot

2. 开发工具

开发工具我使用的是goland,开箱即用,舒服。

语法

定义变量

go使用var关键字来声明变量,这个和js一致,哈哈。

package main

import "fmt"

func variableInitialValue() {
    // 变量名后面就是变量类型
    var a int = 3
    var s string = "abc"
    fmt.Println(a, s)
}
variableInitialValue() // 3 abc
复制代码

另外,假如你只是定义变量但是没有赋值,go中是有初值的例如int会是0string会是空字符串。这一点和js就不一样了。

另外,go是可以自动推断变量类型的。

func variableTypeDeduction() {
    var a, b, c = 3, "a", true
	fmt.Println(a, b, c)
}
variableTypeDeduction() // 3 a true
复制代码

同时,go也为在函数内声明变量提供了简便方式, 这里重点看一下函数内这三个关键字。

func variableShortCut() {
    a, b, c := 3, "a", true
    fmt.Println(a, b, c)
}
variableShortCut() // 3 a true
复制代码

上面我们提到注意函数内这三个字,为什么呢?

package main

import "fmt"

var a = 1 //没有问题
b := 2 // 这句话是错的,在函数外不可以这样写
复制代码

我们注意到文件开头都有个package main,也就是说,go中没有全局变量,只有包内的变量。

另外,同时声明多个变量我们可以这样写:

var (
    a = 1
    b = 2
    c = 3
)
复制代码
内建变量类型
  • bool, string
  • (u)int,(u)int8,(u)int16,(u)int32,(u)int,uintptr
  • byte, rune
  • float32, float, complex, complex128

rune就是go中的char类型。byte是8位的,rune是32位的。complex是复数。

强制类型转换

下面我们看一下代码:

func triangle() {
    var a, b int = 3, 4
    var c int
    c = int(math.Sqrt(float(a*a + b*b)))
    fmt.Println(c)
}
复制代码

我想象中的写法就是math.Sqrt(a*a + b*b),但是会报错,必须要照上面的写法。这样在大型项目中,会帮助我们规避很多BUG。

常量定义

go中定义常量使用的是const,和ES6中的定义方法一样唉。使用方法和var一样,但不能缩写。

const a = "2"
复制代码
枚举类型
func enums() {
    const (
    	cpp = iota
    	java
    	python
    	golang
    	js
    )

    // b, kb, mb, gb, tb, pb
    const (
    	b = 1 << (10 * iota)
    	kb
    	mb
    	gb
    	tb
    	pb
    )

    fmt.Println(cpp, java, python, js)
    fmt.Println(b, kb, mb, gb, tb, pb)
}
enums() 
// 0 1 2 4
// 1 1024 1048576 1073741824 1099511627776 11259906842624
复制代码

iota是自增的意思,并且还可以参加运算。

if else

if和for候面的条件都没有括号

package main

import (
	"fmt"
	"io/ioutil"
)

func main() {
    const filename = "a.txt"
    if contents, err := ioutil.ReadFile(filename); err != nil {
    	fmt.Println(err)
    } else {
    	fmt.Printf("%s\n", contents)
    }
    // 以下代码都不到contents
    // fmt.Printf("%s\n", contents)
}
复制代码

请注意一下if contents, err := ioutil.ReadFile(filename); err != nil {}这个写法,虽然从可读性上我不怎么认同,但是我看网上有人说是在结束ifelse之后,contents变量就会被自动回收,因为contents写在了if语句的作用域内。

switch

go中switch会自动break,除非使用fallthrough

func grade(score int) string {
    g := ""
    switch {
    case score < 0 || score > 100:
    	panic(fmt.Sprintf("Wrong score: %d", score))
    case score < 60:
    	g = "F"
    case score < 80:
    	g = "C"
    case score < 90:
    	g = "B"
    case score <= 100:
    	g = "A"
    }
    return g
}
复制代码
for

写一个整数转为二进制树的函数

import (
	"fmt"
	"strconv"
)
func convertToBin(n int) string {
    res := ""
    for ; n > 0; n/=2 {
    	lsb := n % 2
    	res = strconv.Itoa(lsb) + res
    }
    return res
}
convertToBin(13) // 1101
复制代码

另外。go语言中没有while,直接使用for就可以,我们写一个一行一行读文件的函数。

import (
	"fmt"
	"os"
	"bufio"
)

func printFile(filename string) {
    file, err := os.Open(filename)
    if err != nil {
    	panic(err)
    }
    
    scanner := bufio.NewScanner(file)
    
    for scanner.Scan() {
    	fmt.Println(scanner.Text())
    }
}
printFile("a.txt")
// lemon
// lemonfe
复制代码

函数定义

上面我们已经写了好多函数了,现在我们来看一个函数返回多个值的例子

func div(a, b int) (q, r int) {
    return a + b, a - b
}
q, r := div(1, 2)
t, _ := div(3, 4)
fmt.Println(q, r, t) // 3 -1 7
复制代码

为什么使用了_呢?因为go中不允许定义了变量而不使用。

多个返回值的使用场景一般都是返回err

func div(a, b int) (int, err){
    ...
}
复制代码
参数是一个函数
package main

import (
	"fmt"
	"reflect"
	"runtime"
)

func add(a, b int) int {
    return a + b
}

func apply(op func(int, int) int, a, b int) int {
    // 拿到函数的名字
    p := reflect.ValueOf(op).Pointer() //拿到函数的指针
    opName := runtime.FuncForPC(p).Name()
    fmt.Println(opName, a, b)
    return op(a, b)
}
func main() {
    fmt.Println(apply(add, 3, 4))
}
复制代码

运行结果:

main.add 3 4
7
复制代码
可变参数列表
func sum(nums ...int) int {
    s := 0
    for i := range nums {
    	s += nums[i]
    }
    return s
}
func main() {
    fmt.Println(sum(1,2,5,5,7,4))
}
复制代码

运行结果: 24

指针

var a int = 3
var pa *int = &a
*pa = 4
复制代码
  • &a 代表变量a的指针
  • var pa *int = &a声明一个指针,指向a
  • *pa其实就是a的值

我们来实现一个交换两个变量值的函数:

func swap(a, b *int)  {
    *a, *b = *b, *a
}
func main() {
    a, b := 3, 4
    swap(&a, &b)
    fmt.Println(a, b)
}
复制代码

运行结果:

4 3
复制代码

转载于:https://juejin.im/post/5b9f9d6fe51d450ea401cad2

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- 7swz.com 版权所有 赣ICP备2024042798号-8

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务