对于语言设计之争, 唯一需要牢记的一句话是: 如果把 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. vmware新建Ubuntu时,提示此主机不支持 Intel VT-x

    有两种解决方式 一.BIOS中打开CPU虚拟选项,不同厂商主板配置不同: 以下以个人thinkpad T460P电脑为例: 1.关机,开机,在启动时,按F1今天 BIOS 设置页面: 2.选择 Sec ...

  2. 基于pandas python sklearn 的美团某商家的评论分类(文本分类)

    美团店铺评价语言处理以及分类(NLP) 第一篇 数据分析部分 第二篇 可视化部分, 本文是该系列第三篇,文本分类 主要用到的包有jieba,sklearn,pandas,本篇博文主要先用的是词袋模型( ...

  3. inline-blcok 之间的空白间隙

    前言: inline-blcok 布局时,通常情况下, inline-blocks 之间有空白,尽管通常我们是不想要的,毕竟不像padding或者margin一样好控制,如图: <div cla ...

  4. VS2015:出现devenv.sln解决方案保存对话框

    问题描述: 打开VS2015项目时,提示保存“devenv.sln” 解决方法: 找到文件:C:\Program Files (x86)\Common Files\microsoft shared\M ...

  5. xtrabackup安装部署(二)

    在官网中,复制相关链接下载最新版本(建议使用当前发布版本前6个月左右的稳定版本) https://www.percona.com/downloads/XtraBackup/LATEST/ 1.下载和安 ...

  6. 经典 mysql 28道题

    1.登陆MySQL数据库. mysql -uroot -pdadong123 2.查看当前登录的用户. select user(); select user from mysql.user; 3.创建 ...

  7. Check access restrictions in Zabbix agent configuration

    配置自定义监控K值时,出现下面错误提示 [root@manage ~]# zabbix_get -s -k "login_user" zabbix_get []: Check ac ...

  8. Timer应用之Interval优化

    开发中, 有时有这种场景,使用 Timer 的 Timer_Elapsed 间隔  执行(如:从数据库)获取数据 与 现有 应用服务器中的 静态变量数据(起到缓存的目的)做 对比 ,若有改变,则 更新 ...

  9. 170809、 把list集合中的数据按照一定数量分组

    /** * @Desc : 切分list位多个固定长度的list集合(我这是业务需要,直接是1w条数据切分) * @Author : RICK * @Params: [historyList] * @ ...

  10. 【紫书】Play on Words UVA - 10129 欧拉回路

    题意:给你1e5个字符串,若前一个的末尾字母等于当前的首字母,则可以连在一起(成语接龙一个意思)判断是否可以将他们连在一起 题解:将首位看作点,单词看作边.变成欧拉回路问题. 判断出入度是否相等,再用 ...