Go 语言编程实例(五)

本节主要分享:延迟(defer),集合,字符串函数,字符串格式。

以下代码在存放于github中如下仓库:github

Go延迟(defer)实例

defer用于确保稍后在程序执行中执行函数调用,通常用于清理目的。延迟(defer)常用于例如,ensurefinally 常见于其他编程语言中。

假设要创建一个文件,写入内容,然后再完成之后关闭。这里可以这样使用延迟(defer)处理。

在使用 createFile 获取文件对象后,立即使用closeFile推迟该文件的关闭。这将在writeFile() 完成后封装函数 (main)结束时执行。

package main

import (
    "os"
    "fmt"
)

func main(){
    f := createFile("defer_panic_test.txt")
    defer closeFile(f)
    writeFile(f)
}

func createFile(p string) *os.File{
    fmt.Println("creating")
    f,err := os.Create(p)
    if err != nil{
        panic(err)
    }
    return f
}

func writeFile(f *os.File){
    fmt.Println("writing")
    fmt.Fprintln(f,"data")
}

func closeFile(f *os.File){
    fmt.Println("closing")
    f.Close()
}

Go 集合函数实例

我们经常需要在程序中对数据集合执行操作,例如选择满足给定集合的项目,或者将所有项目映射到具有自定义函数的新集合。

在某些语言中,通用数据结构和算法是惯用的。Go 不支持泛型。

这里是一些字符串切片的示例收集函数。可以使用这些示例来构建自己的函数。注意,某些情况下,直接内联集合操作代码可能是最清楚的,而不用创建和调用辅助函数。

代码实现功能如下:返回目标字符串 t 的第一个索引,如果没找到就返回 -1 。如果目标字符串 t 在切片中,则返回 true。如果切片中的第一个字符串满足词 f ,则返回 true。 如果切片中所有的字符串都满足 f ,则返回 true。返回一个新的切片,包含将函数 f 应用于原始切片中的每一个字符串的结果。

package main

import (
    "fmt"
    "strings"
)

//找寻单词排第几
func Index(vs []string,t string ) int{
    for i,v := range vs {
        if v == t {
            return i
        }
    }
    return -1
}

//判断是否包含有该单词
func Include(vs []string,t string) bool{
    return Index(vs,t)>=0
}

//当含有目标单词,返回true
func Any(vs []string, f func(string) bool) bool{
    for _,v := range vs{
        if f(v) {
            return true
        }
    }
    return false
}
//当所有单词都在里面时,才返回true
func All(vs [] string,f func(string)bool)bool{
    for _,v := range vs{
        if !f(v){
            return false
        }
    }
    return true
}

//过滤包含某单词的
func Filter(vs []string, f func(string)bool) []string{
    vsf := make([]string , 0)
    for _,v := range vs {
        if f(v){
            vsf = append(vsf,v)
        }
    }
    return vsf
}
//新切片
func Map(vs []string, f func(string)string)[]string{
    vsm := make([]string,len(vs))
    for i,v := range vs{
        vsm[i] = f(v)
    }
    return vsm
}

func main(){
    var strs = []string{"peach","apple","pear","plum"}

    fmt.Println(Index(strs,"pear"))

    fmt.Println(Include(strs,"grape"))

    fmt.Println(Any(strs, func(v string) bool {
        return strings.HasPrefix(v,"p")
    }))

    fmt.Println(All(strs, func(v string) bool {
        return strings.HasPrefix(v,"p")
    }))

    fmt.Println(Filter(strs, func(v string) bool {
        return strings.Contains(v,"e")
    }))

    fmt.Println(Map(strs,strings.ToUpper))

}

Go字符串函数实例

标准库的字符串包提供了许多有用的字符串相关函数。这里有一些例子就像是用一个包的感觉。将 fmt.Println 取一个别名,缩写成一个较短的名称,下面示例代码中将使用它。

下面是一些来自包的函数,而不是字符串对象本身的方法,所以我们需要将待处理字符串作为函数的第一个参数传入。还有更多的函数可以在 字符串包 的文档中找到。

注意: Len 函数和索引均工作在字节级别上。Go 使用 UTF-8 编码字符串,如果使用潜在的多字节字符,将需要使用编码转换操作。

package main

import (
    "fmt"
    s "strings"
)

var p = fmt.Println


func main(){

    //在 http://golang.org/pkg/strings/ 中有更多的解释
    p("Contains:  ",s.Contains("test","es"))

    p("Count:     ",s.Count("Test","t"))
    p("HasPrefix: ",s.HasPrefix("test","te"))
    p("HasSuffix: ",s.HasSuffix("test","st"))
    p("Index:     ",s.Index("test","e"))
    p("Join:      ",s.Join([]string{"a","b"},"-"))
    p("Repeat:    ",s.Repeat("a",5))
    p("Replace:   ",s.Replace("foo","o","0",-1))
    p("Replace:   ",s.Replace("foo","o","0",1))
    p("Split:     ",s.Split("a-b-c-d-e","-"))
    p("ToLoer:    ",s.ToLower("TEST"))
    p("ToUpper:   ",s.ToUpper("test"))
    p()

    p("Len:       " ,len("Hello"))
    p("Char:       ","Hello"[1])

}

Go字符串格式实例

Go 语言为传统的 Printf 字符串格式化输出提供了极好的支持。以下是常见的字符串格式化示例。

Go 提供了几种打印动词,设计用于格式化一般的值。

如果值是一个结构体, %+v 变体将包括结构体的字段名。

%#v 变体打印Go语法表示,将会生成该值的源代码片段。

要打印值的类型,请使用 %T。格式化布尔是比较直接了当的。有许多格式化整数的选项。对于标准的 base-10 格式化,请使用 %d

package main

import (
    "fmt"
    "os"
)

type point struct {
    x,y int
}

func main(){
    p := point{1,2}
    fmt.Printf("%v\n" ,p)
    fmt.Printf("%+v\n",p)
    fmt.Printf("%#v\n",p)
    fmt.Printf("%T\n" ,p)

    fmt.Printf("%t\n",true)

    fmt.Printf("%d\n",123)

    //二进制形式打印
    fmt.Printf("%b\n",p)
    //字符串形式
    fmt.Printf("%c\n",33)
    //十六进制
    fmt.Printf("0x%x\n",456)
    //浮点
    fmt.Printf("%f\n",78.9)

    //不同的科学计数法
    fmt.Printf("%e\n",123400000.0)
    fmt.Printf("%E\n",123400000.0)

    //基本字符串输出
    fmt.Printf("%s\n","\"string\"")

    fmt.Printf("%q\n","\"string\"")
    //十六进制打印
    fmt.Printf("%x\n","hex this")
    //指针
    fmt.Printf("%p\n",&p)

    /*含间距格式化*/
    fmt.Printf("|%6d|%6d|\n",12,345)
    //使用 - 可以左对齐
    fmt.Printf("|%-6.2f|%-6.2f|\n",1.2,3.45)
    fmt.Printf("|%6.2f|%6.2f|\n",1.2,3.45)

    fmt.Printf("|%6s|%6s|\n","foo","b")
    fmt.Printf("|%-6s|%-6s|\n","foo","b")

    //sprintf也有的
    s := fmt.Sprintf("a %s","string")
    fmt.Println(s)

    //错误通道打印信息
    fmt.Fprintf(os.Stderr,"an %s\n","error")
}

Go 正则表达式实例

Go 提供了对正则表达式的内置支持,下面是Go 常见的 regexp 的一部分例子。正则表达式本身很强大,规则需要多用才能够熟练。

package main

import (
    "regexp"
    "fmt"
    "bytes"
)

func main(){
    //测试规则是否能匹配字符串
    match,_:=regexp.MatchString("p([a-z]+)ch","peach")
    fmt.Println(match)

    //使用regexp其他函数的时候需要先 使用 compile 函数进行优化
    r,_:= regexp.Compile("p([a-z]+)ch")

    fmt.Println(r.MatchString("peach"))
    //找寻符合规则的字符串
    fmt.Println(r.FindString("peach punch"))
    //找寻符合规则的字符串所在位置 这里返回时开始和结束的位置
    fmt.Println(r.FindStringIndex("peach punch"))
    //匹配 "p([a-z]+)ch" 和 "([a-z]+)" 两个表达式
    fmt.Println(r.FindStringSubmatch("peach punch"))
    //匹配上面两个表达式找到的字符所在的位置
    fmt.Println(r.FindStringSubmatchIndex("peach punch"))
    //找寻所有符合的字符串
    fmt.Println(r.FindAllString("peach punch pinch",-1))
    //找寻所有子规则符合的字符串所在位置
    fmt.Println(r.FindAllStringSubmatchIndex("peach punch pinch",-1))
    //限制只找两个
    fmt.Println(r.FindAllString("peach punch pinch",2))

    fmt.Println(r.Match([]byte("peach")))

    r = regexp.MustCompile("p([a-z]+)ch")
    fmt.Println(r)

    fmt.Println(r.ReplaceAllString("a peach","<fruit>"))

    in  := []byte("a peach")
    out := r.ReplaceAllFunc(in,bytes.ToUpper)
    fmt.Println(string(out))
}

如需进一步讨论可以加群:295023494

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容

  • 出处---Go编程语言 欢迎来到 Go 编程语言指南。本指南涵盖了该语言的大部分重要特性 Go 语言的交互式简介,...
    Tuberose阅读 18,396评论 1 46
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,585评论 18 139
  • 官方网站:https://golang.org/标准库文档:https://golang.org/pkg/在线编码...
    技术学习阅读 2,323评论 2 39
  • 郭相麟 出门在外冷暖自知,某天下午我的时间在走错路、绕远路,来回倒腾中度过! 方向不清晰,依赖着导航给出的方向...
    郭相麟阅读 254评论 0 0
  • 那条路 想来只是一条寂寥的单行道 沿途没有依稀可识的物种 供你回来时认领,你 还会回来的吗 翻开渐行渐远的往事 往...
    江城妖怪阅读 315评论 1 3