Go语言中的switch语句
switch语句在Go语言中有着非常重要的作用,因为它不仅可以用于常见的条件判断,还可以结合正则表达式进行更复杂的字符串匹配。下面我们首先来看一个简单的switch语句示例:
switch asString {
case "1":
fmt.Println("一!")
case "0":
fmt.Println("零!")
default:
fmt.Println("不关心!")
}
上面的switch代码块可以区分"1"、"0"字符串,并为其他所有输入执行默认操作(default分支)。然而,switch语句还可以更加灵活和适应复杂的条件:
switch {
case number < 0:
fmt.Println("小于零!")
case number > 0:
fmt.Println("大于零!")
default:
fmt.Println("零!")
}
这个switch代码块可以识别传入的数值是正数、负数还是零。如你所见,switch语句的各个分支可以包含条件表达式。
switch与正则表达式结合使用
switch不仅可以处理简单的值判断,还可以通过正则表达式来进行复杂的字符串匹配。以下示例展示了如何在switch语句中使用正则表达式进行字符串模式匹配:
var negative = regexp.MustCompile(`-`)
var floatingPoint = regexp.MustCompile(`\d?\.\d`)
var email = regexp.MustCompile(`^[^@]+@[^@.]+\.[^@.]+`)
switch {
case negative.MatchString(asString):
fmt.Println("负数")
case floatingPoint.MatchString(asString):
fmt.Println("浮点数!")
case email.MatchString(asString):
fmt.Println("这是一个邮箱!")
fallthrough
default:
fmt.Println("其他内容!")
}
在这个例子中,我们定义了三个正则表达式:negative
用于匹配负数,floatingPoint
用于匹配浮点数,email
用于匹配电子邮件地址。我们通过switch
语句和regexp.MatchString
函数来检查字符串是否匹配这些模式。如果匹配到邮箱格式,会执行fallthrough
语句,继续执行default
分支输出“其他内容”。
switch的类型判断
除了用于常见的值和模式匹配,switch还可以用于类型判断。以下是一个用于类型断言的switch示例:
var aType error = nil
switch aType.(type) {
case nil:
fmt.Println("是nil接口!")
default:
fmt.Println("不是nil接口!")
}
在这个代码中,switch
通过类型断言来判断aType
是否为nil
接口,并根据实际类型执行相应的逻辑。通过这种类型判断,Go语言可以在运行时进行动态类型检查和操作。
运行switch.go示例
当我们用不同的输入参数运行switch.go
时,会产生如下输出:
$ go run switch.go
usage: switch number.
exit status 1
$ go run switch.go mike@g.com
This value is not an integer: 0
Do not care!
It is an email!
Something else!
It is nil interface!
$ go run switch.go 5
Bigger than zero!
Five!
Something else!
It is nil interface!
$ go run switch.go 0
Zero!
Zero!
Something else!
It is nil interface!
$ go run switch.go 1.2
This value is not an integer: 0
Do not care!
Floating point!
It is nil interface!
$ go run switch.go -1.5
This value is not an integer: 0
Do not care!
Negative number
It is nil interface!
这些例子展示了如何使用switch
来处理整数、字符串、浮点数、邮箱地址以及不同的类型。
用Go语言计算高精度的圆周率
在本节中,我们将使用Go语言中的math/big
包和该包提供的特殊类型来计算高精度的圆周率。calculatePi.go
是一个使用Bellard公式来计算圆周率的程序,它由四个部分组成。
首先是程序的第一部分:
package main
import (
"fmt"
"math"
"math/big"
"os"
"strconv"
)
var precision uint = 0
precision
变量存储了所需的计算精度,并作为全局变量,使其能够在程序的任何地方被访问。
第二部分代码如下:
func Pi(accuracy uint) *big.Float {
k := 0
pi := new(big.Float).SetPrec(precision).SetFloat64(0)
k1k2k3 := new(big.Float).SetPrec(precision).SetFloat64(0)
k4k5k6 := new(big.Float).SetPrec(precision).SetFloat64(0)
temp := new(big.Float).SetPrec(precision).SetFloat64(0)
minusOne := new(big.Float).SetPrec(precision).SetFloat64(-1)
total := new(big.Float).SetPrec(precision).SetFloat64(0)
two2Six := math.Pow(2, 6)
two2SixBig := new(big.Float).SetPrec(precision).SetFloat64(two2Six)
new(big.Float)
用于创建一个具有指定精度的big.Float
变量。通过调用SetPrec()
方法,可以设置所需的精度。
第三部分代码:
for {
if k > int(accuracy) {
break
}
// Bellard公式的计算
pi.Add(pi, total)
k++
}
pi.Quo(pi, two2SixBig)
return pi
}
这个循环执行Bellard公式的核心计算,并不断累加计算结果。最终将结果除以two2SixBig
,得到高精度的圆周率。
程序的最后部分:
func main() {
arguments := os.Args
if len(arguments) == 1 {
fmt.Println("请提供一个数值参数!")
os.Exit(1)
}
temp, _ := strconv.ParseUint(arguments[1], 10, 32)
precision = uint(temp) * 3
PI := Pi(precision)
fmt.Println(PI)
}
当我们运行这个程序时,如果没有提供参数,它会提示提供一个数值参数。例如,当我们输入20
时,程序会输出20位精度的圆周率:
$ go run calculatePi.go 20
3.141592653589793258
对于更高的精度,程序会计算出更长的圆周率。
开发简易键值对存储系统
在本节中,我们将学习如何使用Go语言开发一个简易的键值对存储系统。这个系统的目标是快速响应查询并尽可能提高效率,使用简单的算法和数据结构即可实现。
核心功能
该键值对存储系统支持以下基本操作:
- 添加新元素
- 根据键删除现有元素
- 查找存储中指定键的值
- 修改现有键的值
以下是实现添加和删除元素的代码:
func ADD(k string, n myElement) bool {
if k == "" {
return false
}
if LOOKUP(k) == nil {
DATA[k] = n
return true
}
return false
}
func DELETE(k string) bool {
if LOOKUP(k) != nil {
delete(DATA, k)
return true
}
return false
}
这个程序使用Go语言的map
数据结构来存储键值对。map
提供了高效的查找和删除操作。
查找与修改操作
下面是查找和修改键值对的代码实现:
func LOOKUP(k string) *myElement {
_, ok := DATA[k]
if ok {
n := DATA[k]
return &n
} else {
return nil
}
}
func CHANGE(k string, n myElement) bool {
DATA[k] = n
return true
}
当查找一个不存在的键时,程序返回nil
,而修改操作则直接替换指定键的值。
程序执行的输出如下:
$ go run keyValue.go
ADD 123 1 2 3
ADD 234 2 3 4
ADD 345
PRINT
key: 123 value: {1 2 3}
key: 234 value: {2 3 4}
key: 345 value: { }
Go语言中的JSON与XML处理
Go语言内置了对JSON和XML格式的支持,使得我们可以轻松地进行数据的序列化和反序列化。
JSON处理
以下是读取JSON数据的代码:
func loadFromJSON(filename string, key interface{}) error {
in, err := os.Open(filename)
if err != nil {
return err
}
decodeJSON := json.NewDecoder(in)
err = decodeJSON.Decode(key)
if err != nil {
return err
}
in.Close()
return nil
}
这个函数从指定的JSON文件中读取数据并解码到Go结构体中。
XML处理
类似于JSON,Go的encoding/xml
包也可以处理XML数据。以下是将数据转换为XML的代码:
type Employee struct {
XMLName xml.Name `xml:"employee"`
Id int `xml:"id,attr"`
FirstName string `xml:"name>first"`
LastName string `xml:"name>last"`
Initials string `xml:"name>initials"`
}
通过定义XML标签,我们可以灵活地控制结构体字段的XML输出格式。
总结
通过学习Go语言中的switch
语句、正则表达式、高精度数学计算、键值对存储、JSON和XML的处理,我们能够处理更复杂的编程任务。这些工具和技术为开发者提供了强大的处理能力,可以应对各种不同的应用场景。