对于语言设计之争, 唯一需要牢记的一句话是: 如果把 C 变成 C++, 那么 C 就消失了。

Go 是一个轻量级的简洁的支持并发的现代语言,  可以用于探索性个人项目, 这是我想学这门语言的主要原因。 对于有一定编程经验的人来说, 学习一种新语言的方式是, 先概览下语言特性, 然后编写一个中等规模的程序, 尽可能地运用到大部分重要特性。

Go 的主要语言特性:

l 1.  静态类型 + 类型推导;

          l 2.  简化的控制结构: if , for , switch;
          l 3.  可命名的多返回值的函数;
          l 4.  内置容器支持: 数组、Slice、Map ;
          l 5.  简化的指针与引用;
          l 6.  简化的对象特性: 结构体与非侵入式接口;
          l 7.  内置的并发支持: go, Goroutine & Channel ;
          l 8.  反射、匿名函数与闭包;
          l 9.  便捷地 CGo 交互;
          l 10. 内置 GC ;
          l 11. 包管理。
 

下面的程序用于计算一个目录下所有文件或目录的大小。

$ go build -o dirsize dirsize_module.go time2.go

$ dirsize

dirsize_module.go

package main

import (
"fmt"
// "log"
"os"
"sort"
"time"
) import "C" type ShortFileInfo struct {
fileName string
size int64
} type FileInfoSlice []ShortFileInfo func (fileInfo *ShortFileInfo) Desc() string {
return fmt.Sprintf("{%s:%s}", fileInfo.fileName, readableSize(fileInfo.size))
} func (fileInfos FileInfoSlice) Len() int {
return len(fileInfos)
} func (fileInfos FileInfoSlice) Swap(i, j int) {
fileInfos[i], fileInfos[j] = fileInfos[j], fileInfos[i]
} func (fileInfos FileInfoSlice) Less(i, j int) bool {
return fileInfos[i].size > fileInfos[j].size
} type IOError struct {
msg string
err error
} func (ioe IOError) Error() string {
return "Error: " + ioe.msg + "\nCause: " + ioe.err.Error()
} func produceFiles(dirName string) (fileInfos []os.FileInfo, e error) {
path, err := os.Open(dirName)
if err != nil {
//log.Fatal(err)
return nil , IOError{"failed to open " + dirName, err}
}
defer path.Close()
fileInfos, readerr := path.Readdir()
if readerr != nil {
//log.Fatal(readerr)
return nil, IOError{"failed to read " + dirName, readerr}
}
return fileInfos, nil
} func procFile(fileInfo os.FileInfo, baseDirName string, channelBuffer chan ShortFileInfo) {
var filesize int64
fileName := fileInfo.Name()
if fileInfo.IsDir() {
filesize = totalFilesizeInDir(fileInfo, baseDirName)
} else {
filesize = fileInfo.Size()
}
shortFileInfo := ShortFileInfo{fileName, filesize}
fmt.Println(time.Now().String() + " store: " + shortFileInfo.Desc())
channelBuffer <- shortFileInfo
} func totalFilesizeInDir(fileInfo os.FileInfo, baseDirName string) int64 {
var filesize int64 =
fileInfos, _ := produceFiles(baseDirName + "/" + fileInfo.Name())
for _, subfileInfo := range fileInfos {
if subfileInfo.IsDir() {
filesize += totalFilesizeInDir(subfileInfo, baseDirName+"/"+fileInfo.Name())
} else {
filesize += subfileInfo.Size()
}
}
return filesize
} func sleep(ns int) {
time.Sleep(time.Duration(time.Second) * time.Duration(ns))
} const (
B int64 =
KB int64 =
MB int64 = *
GB int64 = * *
TB int64 = * * *
) const formatF string = "%8.4f" func readableSize(sizeInBytes int64) string {
switch {
case B <= sizeInBytes && sizeInBytes < KB:
return fmt.Sprintf("%dB", sizeInBytes)
case KB <= sizeInBytes && sizeInBytes < MB:
return fmt.Sprintf(formatF+"KB", float64(sizeInBytes)/float64(KB))
case MB <= sizeInBytes && sizeInBytes < GB:
return fmt.Sprintf(formatF+"MB", float64(sizeInBytes)/float64(MB))
case GB <= sizeInBytes && sizeInBytes < TB:
return fmt.Sprintf(formatF+"GB", float64(sizeInBytes)/float64(GB))
case TB <= sizeInBytes:
return fmt.Sprintf(formatF+"TB", float64(sizeInBytes)/float64(TB))
default:
return ""
}
} //export mainProc
func mainProc() { start_1 := time.Now().Unix() baseDirName := "/home/lovesqcc"
//baseDirName := "/notExist"
//baseDirName := "/" fileList, err := produceFiles(baseDirName)
if err != nil {
fmt.Println(err.Error())
os.Exit()
}
fileNumber := len(fileList)
channelBuffer := make(chan ShortFileInfo, fileNumber)
fileInfoMap := make(map[string]int64, fileNumber) for _, fileInfo := range fileList {
go procFile(fileInfo, baseDirName, channelBuffer)
} var fileInfos = make([]ShortFileInfo, fileNumber+) timeout := make(chan int, )
go func() {
secs :=
sleep(secs)
timeout <- secs
}() for count := ; count <= fileNumber; {
select {
case fileInfo := <-channelBuffer:
fmt.Println(time.Now().String() + " fetch: " + fileInfo.Desc())
fileInfoMap[fileInfo.fileName] = fileInfo.size
fileInfos[count] = fileInfo
count++
case secs := <- timeout:
fmt.Printf("%d s timout ! Exit Loop\n", secs)
os.Exit()
default:
if count == fileNumber {
close(channelBuffer)
}
fmt.Println("Waiting for data ...")
}
}
sort.Sort(FileInfoSlice(fileInfos)) for _, fileInfo := range FileInfoSlice(fileInfos) {
fmt.Println("File " + fileInfo.fileName + " : " + readableSize(fileInfo.size))
} var totalSize int64
totalSize =
for _, filesize := range fileInfoMap {
totalSize += filesize
}
fmt.Printf("Total size in %s:%dB %s\n", baseDirName, totalSize, readableSize(totalSize)) end_1 := time.Now().Unix()
fmt.Printf("start=%d, end=%d\n",start_1, end_1)
fmt.Printf("Time cost: %dms\n", (end_1-start_1)*)
}

time2.go

package main

/*
#include<stdio.h>
#include<time.h> extern int mainProc(); int printTimeCost() {
printf("exec printTimeCost");
time_t start = 0, end = 0;
long duration = 0;
start = time(NULL);
mainProc();
end = time(NULL);
duration = (end - start) *1000;
return duration;
}
*/
import "C"
import "fmt"
func main() {
fmt.Printf("cost: %dms\n", C.int(C.printTimeCost())) }

参考资料:

1.  《Go语言编程》 许式伟著。

2.   Go 轻松学:     https://github.com/jemygraw/TechDoc

3.   Go 实例学习:  https://gobyexample.com/

4.   Go 并发之美:   http://www.cnblogs.com/yuxingfirst/archive/2012/11/28/2792366.html

5.   Go 文档:       https://go-zh.org/doc/

6.   C-Go 互操作 :  http://tonybai.com/2012/09/26/interoperability-between-go-and-c/

7.   Go 标准库:     http://studygolang.com/pkgdoc

8.   Why Go is Not Good:  http://yager.io/programming/go.html

Go语言初尝的更多相关文章

  1. 初尝Windows 下批处理编程

    本文叫“ 初尝Windows 下批处理编程”是为了延续上一篇“初尝 Perl”,其实对于博主而言批处理以及批处理编程早就接触过了. 本文包括以下内容 1.什么是批处理 2.常用批处理命令 3.简介批处 ...

  2. 初尝 Perl

    本文将阐述以下几方面内容: 1.什么是Perl 2.Perl有什么用 3.Windows 下的Perl环境搭建 4.Perl 版Hello World 5.Perl 语法梗概 6.一些参考资料 什么是 ...

  3. .NET领域驱动设计—初尝(三:穿过迷雾走向光明)

    开篇介绍 在开始这篇富有某种奇妙感觉的文章之旅时我们先短暂的讨论一下关于软件开发方法论的简要: 纵观软件开发方法论,从瀑布模型.螺旋模型.RUP(统一软件开发过程).XP(极限编程).Agile(敏捷 ...

  4. .NET领域驱动设计—初尝(一:疑问、模式、原则、工具、过程、框架、实践)

     .NET领域驱动设计—初尝(一:疑问.模式.原则.工具.过程.框架.实践) 2013-04-07 17:35:27 标签:.NET DDD 驱动设计 原创作品,允许转载,转载时请务必以超链接形式标明 ...

  5. seajs初尝 加载jquery返回null解决学习日志含示例下载

    原文地址:http://www.tuicool.com/articles/bmuaEb 如需demo示例,请点击下方链接下载: http://yunpan.cn/cVEybKs8nV7CF  提取码 ...

  6. 初尝微信小程序2-Swiper组件、导航栏标题配置

    swiper 滑块视图容器. 很多网页的首页都会有一个滚动的图片模块,比如天猫超市首页,滚动着很多优惠活动的图片,用来介绍优惠内容,以及供用户点击快速跳转到相应页面. Swiper不仅可以滚动图片,也 ...

  7. 分布式设计《初尝memcached》

          之前听说过高性能的分布式缓存开源工具,但一直没有真正接触过,如今接触的产品中实用到过分布式缓存.所以决定一探到底.memcached是一个优秀的开源的分布式缓存工具.也是眼下比較火热的分布 ...

  8. Github原生CI/CD,初尝Github Actions

    Github 原生 CI/CD,初尝 Github Actions Intro Github 目前已经推出了自己的 CICD 服务 -- Github Actions,而且比微软的 Azure Dev ...

  9. golang快速入门(五)初尝web服务

    提示:本系列文章适合对Go有持续冲动的读者 初探golang web服务 golang web开发是其一项重要且有竞争力的应用,本小结来看看再golang中怎么创建一个简单的web服务. 在不适用we ...

随机推荐

  1. dubbo入门之helloWorld

    dubbo官方文档:http://dubbo.apache.org/zh-cn/docs/user/quick-start.html 基于spring coloud的demo:http://start ...

  2. 【vue】---项目接口管理---【巷子】

    一.前言 在vue开发中,会涉及到很多接口的处理,当项目足够大时,就需要定义规范统一的接口 假设后端的文档分成了以下几个模块 1.发现模块 2.个人信息模块 3.商品模块 4.评论模块 ...... ...

  3. Docker 学习应用篇三:使用docker搭建的环境,安装thinksns

    Thinksns 是一个开源的社交网站,因为目前的项目需要用到这个,所以就下载一个安装试试看. 之前在windows上用了wamp,安装的很顺利.但是项目是要部署到linux上的.于是我便用了Dock ...

  4. 初识Spring Webflux

    Important to know is that there are two ways to use Spring Webflux. One using annotations, which is ...

  5. 关于ArcGIS Server修改数据源是否对切片服务有影响

    感谢一路走来默默支持和陪伴的你~~~ ------------------欢迎来访,拒绝转载------------------- (一)问题: 一直有人问一个问题: 1.我发布了切片的地图服务一以后 ...

  6. dbAdmin 不等于 root 集合中角色

    dbAdmin  root  集合中角色 use admin创建 db.createUser( { user: "tmp_rw_56756", pwd: "tmp4242 ...

  7. docker and ssh issues

    docker run -i -t qcdatainc/centos-jdkyum update yum install openssh-server ssh -vvv -p 222 jenkins@1 ...

  8. Charles 使用(拦截与修改)

    一.http 拦截(Breakpoints) 选取需要拦截的地址,鼠标右击选择Breakpoints 二.拦截结果与修改 可以在请求与返回结果中修改内容 1.所拦截的数据包 2.所拦截的请求 3.所拦 ...

  9. Git使用常见问题脚本

    receive.denyCurrentBranch 这是由于git默认拒绝了push操作,需要进行设置,修改.git/config添加如下代码: [receive]     denyCurrentBr ...

  10. Linux输入输出重定向和文件查找值grep命令

    Linux输入输出重定向和文件查找值grep命令 一.文件描述符Linux 的shell命令,可以通过文件描述符来引用一些文件,通常使用到的文件描述符为0,1,2.Linux系统实际上有12个文件描述 ...