Golang基础(1)

一、hello world

package main //每个go文件都以package字句开头,package字句给出包的名称,Go文件中的代码称为包的一部分。

import "fmt" //每个文件都需要导入其他包,然后才能使用其他包里包含的代码

func main () {
	fmt.Println("Hello World!","Go") //参数用,号分隔
}
package main

import (
	"fmt" //包名
	"math"
	"strings"
)

func main() {
	fmt.Println(math.Floor(3.14)) //通过包调用函数,例如fmt(包).Println(函数)()
	fmt.Println(strings.Title("head first go"))
}

字符串

“Hello World!”

符文(rune)

‘A’ //单个字符

布尔值

true,false

声明变量

只需要使用var关键字,后跟所需的名称以及变量将要保存值的类型。

var quality int
var length,width float64
var name string

//用=为变量分配该类型的任何值
quality=2
name="go"
//可以一次为多个变量赋值
length,width=1.2,2.4
//如果在声明变量的同时为其赋值,通常可以在声明中省略变量的类型。分配给变量的值类型将用作该变量的类型。
var quality=2
var length,width=1.2,1.4
var name="go"

短变量声明

如果声明变量的时候就知道其值是什么,可以使用短变量声明。不必很明确地声明变量的类型并在之后使用=为其赋值,而是同时使用:=。这里如果忽略了:,quality=2将被视为赋值。

quality:=2 //声明加定义(同时赋值)
length,width:=1.2,2.4
name:="go"

所有声明的变量都必须在程序中使用。

fmt.Println(quality)
fmt.Println(length,width)
fmt.Println(name)

类型

可以通过将任何值传递给reflect包的TypeOf函数,来查看他们的类型。

package main
import (
    "fmt"
    "reflect"
)
func main() {
    fmt.Println(reflect.TypeOf(42)) //int
}

命名规则

  • 名称必须以大写字母开头
    如果变量、函数或类型的名称以大写字母开头,则认为它是导出的,可以从当前包之外访问它,否则只能在当前包中使用。

转换

Go中的数学运算和比较运算要求包含的值具有相同类型。 如果不是的话,则在尝试运行代码时会报错。为变量分配新值也是如此,所赋值的类型与变量申明的类型不匹配也会报错。
转换的目的是允许你将值从一种类型转换为另一种类型。只需提供要将值转换成的类型,后面紧接着是圆括号中要转换的值。

var myInt int = 2
float64(myInt)

quality:=2
length:=1.2
length=float64(quality)

二、条件和循环

调用方法

Go中方法是指:与给定类型的值相关联的函数。有点像成员函数。
在下面的代码中time包中有一个表示日期和时间的Time类型,每一个time.Time值都有一个返回年份的Year方法。

package main

import (
	"fmt"
	"time"
)

func main() {
//time.Now函数返回当前日期和时间的新Time值,将其存储在now变量中。然后对now引用的值调用Year方法。
	var now time.Time = time.Now()
	var year int = now.Year()
	fmt.Println(year)
	fmt.Println(now)
}

方法是与特定类型的值关联的函数。
string包有一个Replacer类型,可以在字符串中搜索子字符串,并且在每次该子字符串出现的地方用另一个字符串替换它:

package main
import (
    "fmt"
    "strings"
)
func main() {
    broken:="G# r#cks!"
    replacer:=strings.NewReplacer("#","o") //将返回strings.Replacer,并设置为将每个"#"替换为"o"
    fixed:=replacer.Replace(broken)//strings.Replacer调用Replace方法,并传递一个字符串进行替换
    fmt.Println(fixed)
}

调用方法与函数有什么区别?
函数属于一个包,而方法属于一个单独的值。这个值出现在圆点的左边。

package main

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

func main() {
    fmt.Print("Enter a grade: ")
    //需要从程序的标准输入中读取输入的方法
    //input, _ := (bufio.NewReader(os.Stdin)).ReadString('\n') //正常输出
    reader:=bufio.NewReader(os.Stdin) //将bufio.Reader保存在reader变量中
    input:=reader.ReadString('\n') //为了实际获取用户输入,调用Reader的ReaderString方法,ReadString方法需要一个带有rune的参数来标记输入结束,也就是说换行符前的所有内容都将被读取
    fmt.Println(input)
}

上述代码中ReadString方法试图返回两个值,实际上运行会报错。
Go中多个返回值最常见的用法是返回一个额外的错误值(err),可以通过查询该错误值来确定函数或方法是否发生了错误。
Go要求声明的每个变量都必须在程序的每个地方使用。如果我们添加了一个err变量,而不检查它,我们的代码将无法通过编译。
代码改进为:

input,err := reader.ReadString('\n') //错误,Go不允许我们声明一个变量,除非我们使用它。
//使用Go的空白标识符忽略错误返回值
input,_ := reader.ReadString('\n')

还可以选择对错误进行处理:添加log包,其中Fatal函数,可以同时为我们完成两项操作:将一条消息记录到终端并停止程序运行。

package main

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

func main() {
    fmt.Print("Enter a grade: ")
    //需要从程序的标准输入中读取输入的方法
    reader:=bufio.NewReader(os.Stdin) //将bufio.Reader保存在reader变量中
    input,err:=reader.ReadString('\n') //为了实际获取用户输入,调用Reader的ReaderString方法,ReadString方法需要一个带有rune的参数来标记输入结束,也就是说换行符前的所有内容都将被读取
    log.Fatal(err)
    fmt.Println(input)
}

条件

运行时我们发现即使程序正常也会停止运行。返回只err为nil,则表示没有错误。但是我们的程序只简单报告nil错误,我们应该做的是,只有当err变量的值不是nil时才退出程序。
实现这一点可以使用条件语句。

input,err:=reader.ReadString('\n')
if err!=nil {
    log.Fatal(err)
}
fmt.Println(input)

将字符串转换为数字

试着写下这样的代码看看会有什么问题。

func main() {
    fmt.Print("Enter a grade: ")
    reader:=bufio.NewReader(os.Stdin) 
    input,err:=reader.ReadString('\n') 
    if err!=nil {
        log.Fatal(err)
    }
    if input >=60 {
        status:="passing"
    } else {
        status:="failing"
    }
}

从键盘输入的内容是作为字符串读入的。上述存在两个问题:

  • 输入的字符串末尾有一个换行符
  • 剩下的字符串需要转换为浮点数
    解决办法:
  • strings包里有一个TrimSpace函数,它将删除字符串开头和结尾的所有空白字符(换行符、制表符和常规空格)input=strings.TrimSpace(input)
  • strconv包的ParseFloat函数将其转换为float64值grade,err:=strconv.ParseFloat(input,64)64为结果的精度位数

Go代码可以分块,即代码段。块通常由大括号{}包围,块可以嵌套。如上面代码中,有if块,函数块,包块以及文件块。

块和变量的作用域

声明的变量都有一个作用域:代码中的可见部分。声明的变量可以在其作用域内的任何地方被访问,但是如果在作用域之外访问它,就会收到一个错误。
上面status作用域局限在if块中,在作用域之外访问status会发生错误。
下面给出一个完整的成绩判断程序:

package main

import (
    "fmt"
    "os"
    "bufio"
    "log"
    "strings"
    "strconv"
)
func main() {
    fmt.Print("Enter a grade: ")
    reader:=bufio.NewReader(os.Stdin)
    input,err:=reader.ReadString('\n')
    if err!=nil {
        log.Fatal(err)
    }
    input=strings.TrimSpace(input)
    grade,err:=strconv.ParseFloat(input,64)
    if err!=nil {
        log.Fatal(err)
    }
    var status string
    if grade >=60 {
        status="passing"
    } else {
        status="failing"
    }
    fmt.Println(grade,"is",status)
    
}

短变量声明中只有一个变量必须是新的

当一个变量名在同一作用域中被声明两次时。我们会得到一个编译错误:

a:=1
a:=2

但是只要短变量声明中至少有一个变量名是新的(没有声明过),这是允许的。新变量名被视为声明,而现有的名字被视为赋值。

a:=1     //声明a
b,a:=2,3 //声明b,赋值a
a,c:=4,5 //赋值a,声明c

一个猜数字的小游戏

//guess challenge players to guess a random number
package main

import (
	"bufio"
	"fmt"
	"log"
	"math/rand"
	"os"
	"strconv"
	"strings"
	"time"
)

func main() {
	seconds := time.Now().Unix() // time.Now()会返回表示当前日期的Time值,Time调用unix方法,它将把时间转换成整数
	rand.Seed(seconds)           // 播种随机种子生成器
	target := rand.Intn(100) + 1 // rand.Intn(100)将返回0~99范围的随机数
	fmt.Println("I've chosen a random number between 1 and 100.")
	fmt.Println("Can you guess it")
	//fmt.Println(target)

	reader := bufio.NewReader(os.Stdin)

	success := false
	for i := 0; i < 10; i++ {
		fmt.Println("You have", 10-i, "guesses left!")
		fmt.Println("Make a guess: ")
		input, err := reader.ReadString('\n')
		if err != nil {
			log.Fatal(err)
		}
		input = strings.TrimSpace(input)  //删除换行符
		guess, err := strconv.Atoi(input) //换成整形
		if err != nil {
			log.Fatal(err)
		}

		if guess > target {
			fmt.Println("Your guess was HIGH!")
		} else if guess < target {
			fmt.Println("Your guess was Low!")
		} else {
			fmt.Println("Your guess was right!")
			success = true
			break
		}
	}
	if !success {
		fmt.Println("Sorry, you didn't guess my number. It was", target)
	}
}
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

是浩浩子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值