Go语言初尝
对于语言设计之争, 唯一需要牢记的一句话是: 如果把 C 变成 C++, 那么 C 就消失了。
Go 是一个轻量级的简洁的支持并发的现代语言, 可以用于探索性个人项目, 这是我想学这门语言的主要原因。 对于有一定编程经验的人来说, 学习一种新语言的方式是, 先概览下语言特性, 然后编写一个中等规模的程序, 尽可能地运用到大部分重要特性。
Go 的主要语言特性:
l 1. 静态类型 + 类型推导;
下面的程序用于计算一个目录下所有文件或目录的大小。
$ 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语言初尝的更多相关文章
- 初尝Windows 下批处理编程
本文叫“ 初尝Windows 下批处理编程”是为了延续上一篇“初尝 Perl”,其实对于博主而言批处理以及批处理编程早就接触过了. 本文包括以下内容 1.什么是批处理 2.常用批处理命令 3.简介批处 ...
- 初尝 Perl
本文将阐述以下几方面内容: 1.什么是Perl 2.Perl有什么用 3.Windows 下的Perl环境搭建 4.Perl 版Hello World 5.Perl 语法梗概 6.一些参考资料 什么是 ...
- .NET领域驱动设计—初尝(三:穿过迷雾走向光明)
开篇介绍 在开始这篇富有某种奇妙感觉的文章之旅时我们先短暂的讨论一下关于软件开发方法论的简要: 纵观软件开发方法论,从瀑布模型.螺旋模型.RUP(统一软件开发过程).XP(极限编程).Agile(敏捷 ...
- .NET领域驱动设计—初尝(一:疑问、模式、原则、工具、过程、框架、实践)
.NET领域驱动设计—初尝(一:疑问.模式.原则.工具.过程.框架.实践) 2013-04-07 17:35:27 标签:.NET DDD 驱动设计 原创作品,允许转载,转载时请务必以超链接形式标明 ...
- seajs初尝 加载jquery返回null解决学习日志含示例下载
原文地址:http://www.tuicool.com/articles/bmuaEb 如需demo示例,请点击下方链接下载: http://yunpan.cn/cVEybKs8nV7CF 提取码 ...
- 初尝微信小程序2-Swiper组件、导航栏标题配置
swiper 滑块视图容器. 很多网页的首页都会有一个滚动的图片模块,比如天猫超市首页,滚动着很多优惠活动的图片,用来介绍优惠内容,以及供用户点击快速跳转到相应页面. Swiper不仅可以滚动图片,也 ...
- 分布式设计《初尝memcached》
之前听说过高性能的分布式缓存开源工具,但一直没有真正接触过,如今接触的产品中实用到过分布式缓存.所以决定一探到底.memcached是一个优秀的开源的分布式缓存工具.也是眼下比較火热的分布 ...
- Github原生CI/CD,初尝Github Actions
Github 原生 CI/CD,初尝 Github Actions Intro Github 目前已经推出了自己的 CICD 服务 -- Github Actions,而且比微软的 Azure Dev ...
- golang快速入门(五)初尝web服务
提示:本系列文章适合对Go有持续冲动的读者 初探golang web服务 golang web开发是其一项重要且有竞争力的应用,本小结来看看再golang中怎么创建一个简单的web服务. 在不适用we ...
随机推荐
- HTML5 Canvas 画纸飞机组件
纸飞机模拟一个物体在规定设计轴线偏离方位. //三角形 function DrawTriangle(canvas, A, B, C) { //画个三角形,“A.B.C”是顶点 with (canvas ...
- JVM源码分析之javaagent原理完全解读
概述 本文重点讲述javaagent的具体实现,因为它面向的是我们Java程序员,而且agent都是用Java编写的,不需要太多的C/C++编程基础,不过这篇文章里也会讲到JVMTIAgent(C实现 ...
- 【CF884F】Anti-Palindromize 费用流
[CF884F]Anti-Palindromize 题意:定义一个串是反回文的,当且仅当对于1<=i<=len,$a_i!=a_{len-i+1}$. 现在给出一个长度为n的串S(n是偶数 ...
- Java秒杀简单设计四:service层设计
接上一篇 https://www.cnblogs.com/taiguyiba/p/9829191.html 封装了系统传递的数据类和异常类 本文继续设计service层设计: 1.SeckillSe ...
- INTRO: THE DAWN (亡灵序曲) 中独白
As the last ship sailed towards the distant horizon I sat there watching on a rock My mind slowly dr ...
- java中String与StringBuilder的区别
相信大家对 String 和 StringBuffer 的区别也已经很了解了,但是估计还是会有很多同志对这两个类的工作原理有些不清楚的地方,今天我在这里重新把这个概念给大家复习一下,顺便牵出 J2SE ...
- Java中-classpath和路径的使用
javac -classpath的使用: javac:如果当前你要编译的java文件中引用了其它的类(比如说:继承),但该引用类的.class文件不在当前目录下,这种情况下就需要在javac命令后面加 ...
- tesseract .net 中使用历程
最近在看文字识别的实例,也查询很多文章,最后还是选定开源的引擎(tesseract3.0.1) 最开始找到的是用微软Office的一个组件实现的,个人感觉不是我想要的(要开源啊才是王道) http:/ ...
- 1.8TF的分类
TF识别手写体识别分类 #-*- coding: utf-8 -*- # @Time : 2017/12/26 15:42 # @Author : Z # @Email : S # @File : 1 ...
- CCCC 排座位 图着色问题
1排座位:https://www.patest.cn/contests/gplt/L2-010 2图着色问题 https://www.patest.cn/contests/gplt/L2-023 建图 ...