对于语言设计之争, 唯一需要牢记的一句话是: 如果把 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. !important:element.style 覆盖样式问题

    问题: 浏览器F12看到是这个样子. 但是我设置的样式是这样子. #iframe_close { width:750px; } 无论怎么设置样式,都无法覆盖掉element.style的样式,widt ...

  2. HDU 3507 - Print Article - [斜率DP]

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3507 Zero has an old printer that doesn't work well s ...

  3. FW 每秒百万级别的 HTTP 请求 sung: 重型的(heavy-duty)、分布式的、多协议测试工具

    本文是构建能够每秒处理 3 百万请求的高性能 Web 集群系列文章的第一篇.它记录了我使用负载生成器工具的一些经历,希望它能帮助每一个像我一样不得不使用这些工具的人节省时间. 负载生成器是一些生成用于 ...

  4. Linux上Oracle 11g安装步骤图解

    Oracle 11g下载地址: http://www.oracle.com/technetwork/database/enterprise-edition/downloads/index.html 选 ...

  5. Qt Creator 4.3.0,Quick Designer里面也看以同时看到和编辑qml code了(Qt5.9的配套IDE)

    作者:Summer Fang链接:https://www.zhihu.com/question/60486611/answer/177584284来源:知乎著作权归作者所有.商业转载请联系作者获得授权 ...

  6. noip做题记录+挑战一句话题解?

    因为灵巧实在太弱辽不得不做点noip续下命QQAQQQ 2018 积木大赛/铺设道路 傻逼原题? 然后傻逼的我居然检查了半天是不是有陷阱最后花了差不多一个小时才做掉我做过的原题...真的傻逼了我:( ...

  7. 在windows中:双击运行Python程序、后台运行Python程序

    在windows中:双击运行Python程序.后台运行Python程序 安装Python解释器的windows环境,如果双击运行*.py的文件,会闪退.怎样避免闪退呢? 我们用python的日志输出程 ...

  8. (3.13)mysql基础深入——mysql日志分析工具之mysqlsla【待完善】

    (3.13)mysql基础深入——mysql 日志分析工具之mysqlsla 关键字:Mysql日志分析工具.mysqlsla 常用工具 [1]mysqldumpslow:官方提供的慢查询日志分析工具 ...

  9. sqlserver 索引的结构及其存储,索引内容

    sqlserver 索引的结构及其存储,sql server索引内容 文章转载,原文地址: http://www.cnblogs.com/panchunting/p/SQLServer_IndexSt ...

  10. Linux文件目录介绍及文件颜色区别

    文件颜色代表含义: 蓝色表示目录: 绿色表示可执行文件: 红色表示压缩文件: 浅蓝色表示链接文件: 白色表示其他文件: 黄色是设备文件,包括block, char, fifo. 常见目录解释 Linu ...