Go语言:基于连接与组合的语言(上)

到目前为止,我做过不下于10次关于Go的讲座,大多数的主题都会与“设计哲学”这样的话题有关。之所 以这样,是因为我对自己的定位是Go语言的“传教士”,而不是“培训师”。我的出发点在于引起大家对Go的 关注与兴趣,至于如何去一步步学习Go语言的语法知识,我相信兴趣是最好的老师。现今我们学习的平台足够 强大,只要你真的很有兴趣,就一定能够学好Go语言。

Go语言是非常简约的语言。简约的意思是少而 精。Go语言极力追求语言特性的最小化,如果某个语法特性只是少些几行代码,但对解决实际问题的难度不会 产生本质的影响,那么这样的语法特性就不会被加入。Go语言更关心的是如何解决程序员开发上的心智负担。 如何减少代码出错的机会,如何更容易写出高品质的代码,是Go设计时极度关心的问题。

Go语言也是 非常追求自然(nature)的语言。Go不只是提供极少的语言特性,并极力追求语言特性最自然的表达,也就是 这些语法特性被设计成恰如多少人期望的那样,尽量避免惊异。事实上Go语言的语法特性上的争议是非常之少 的。这些也让Go语言的入门门槛变得非常低。

今天我的话题重心是关于Go语言编程范式的流派问题。 这仍然是关于“设计哲学”方面的。到目前为止,大家可能听过的编程范式主要如下:

过程式(代表:C)

面向对象(代表:Java、C#)

面向消息(代表:Erlang)

函数式(代表:Haskell、Erlang)

过程式编程的代表概念是过程(函数)。这是一个非常古老的流派,基本上所有语言都有过程式的影子。 但是比较纯粹的过程式的主流语言比较少,通常比较古老,C是其中最典型的代表。

面向对象编程是目 前广为接受、影响极其深远的流派。面向对象有很多概念:如类、方法、属性、重载、多态(虚函数)、构造 和析构、继承等等。Java、C#是其中最典型的代表。Go语言支持面向对象,但将特性最小化。Go语言中有结构 体(类似面向对象中的类),结构体可以有方法,这就是Go对面向对象支持的所有内容。Go语言的面向对象特 征少得可怜。结构体是构成复合对象的基础,只要有组合,通常就由结构体,像C这样的过程式语言,照样有 结构体。所以Go身上没有多少面向对象的烙印,Go 甚至反对继承,拒绝提供继承语法。

面向消息编程 是个比较小众的编程流派,因为分布式与并发编程的强烈诉求而崛起。面向消息编程的主体思想是推荐基于消 息而不是基于锁和共享内存进行并发编程。Erlang语言是面向消息编程的代表。Go语言中有面向消息的影子。 因为Go语言中有channel,可以让执行体(goroutine)之间相互发送消息。但channel只是Go语言的基础语法 特性,Go并没有杜绝锁和共享内存,所以它并不能算面向消息编程流派。

函数式编程也是一个小众的 流派,尽管历史非常悠久。函数式编程中有些概念如:闭包、柯里化、变量不可变等。Haskell、Erlang都是 这个流派的代表。函数式编程之所以小众,个人认为最重要的原因,是理论基础不广为人知。我们缺乏面向函 数式编程的数据结构学。因为变量不可变,数据结构学需要用完全不同思维方式来表达。比如在传统命令式的 编程方式中,数组是最简单的基础数据结构,但函数式编程中,数组这样的数据结构很难提供(修改数组的一 个元素成本太高,Erlang语言中数组这个数据结构很晚才引入,用tree来模拟数组)。Go语言除了支持闭包外 ,没有太多函数式的影子。

Go语言有以上每一流派的影子,但都只是把这些流派的最基础的概念吸收 ,这些特性很基础,很难作为一个流派的关键特征来看。所以从编程范式上来说,个人认为Go语言不属于以上 任何流派。如果非要说一个流派,Go语言类似C++,应该算“多范式”流派的。C++是主流语言中,几乎是唯一 一门大力宣扬多范式编程理念的语言。C++主要支持的编程范式是过程式编程、面向对象编程、泛型编程(我 们上面没有把泛型编程列入讨论的流派之中)。C++对这些流派的主要特性支持都很完整,说“多范式”名副 其实。但Go不一样的是,每个流派的特性支持都很基础,这些特性只能称之为功能,并没有形成范式。

Go语言在吸收这些流派精华的基础上,开创了自己独特的编程风格:一种基于连接与组合的语言。

连接,指的是组件的耦合方式,也就是组件是如何被串联起来的。组合,是形成复合对象的基础。连 接与组合都是语言中非常平凡的概念,但Go语言恰恰是在平凡之中见神奇。

让我们从Unix谈起。Go语 言与Unix、C语言有着极深的渊源。Go语言的领袖们参与甚至主导了Unix和C语言的设计。Ken Thompson 甚至 算得上Unix和C语言的鼻祖。Go语言亦深受Unix和C语言的设计哲学影响。

在Unix世界里,组件就是应 用程序(app),每个app可大体抽象为:

输入:stdin(标准输入), params(命令行参数)

输出:stdout(标准输出)

协议:text (data stream)

不同的应用程序(app)如何连接?答案是:管道(pipeline)。在Unix世界中大家对这样的东西已经很熟 悉了:

app1 params1 | app2 params2

通过管道(pipeline),可以将一个应用程序的输 出(stdout)转换为另一个应用程序的输入(stdin)。更为神奇的一点,是这些应用程序是并行执行的。 app1每产生一段输出,立即会被app2所处理。所以管道(pipeline)称得上是最古老,同时也是极其优秀的并 行设施,简单而强大。

需要注意的是,Unix世界中不同应用程序直接是松散耦合的。上游app的输出是 xml还是json,下游app需要知晓,但并无任何强制的约束。同一输出,不同的下游app,对协议的理解甚至都 可能并不相同。例如,上游app输出一段xml文本,对于某个下游app来说,是一颗dom树,但对linecount程序 来说只是一个多行的文本,对于英文单词词频统计程序来说,是一篇英文文章。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索编程
, app低内存
, 面向对象
, go
, 语言
, 编程语言
, 语言编程
, goroutine
, 范式
, go语言
, go语言编程
, 组合输出
, 特性
流派
,以便于您获取更多的相关知识。

时间: 2024-08-04 03:00:10

Go语言:基于连接与组合的语言(上)的相关文章

insert-jsp语言如何连接mysql数据库

问题描述 jsp语言如何连接mysql数据库 jsp语言如何连接mysql数据库,进行表的增删改查?OA系统设计连接数据库,mysql驱动包在哪儿下载? 解决方案 在页面嵌入脚本代码,然后和在java中操作一样.只是,为什么要在页面上操作呢?这样页面编码可读性变得很糟糕,而且对于后期维护影响非常不好.最主要的是,这么设计没有主次,没有模式,对于横向扩展或者代码复用性都很不好. 解决方案二: jsp连接mysql数据库JSP 连接MYSQL数据库JSP连接MYSQL数据库 解决方案三: 建议你搜索

基于嵌入式SQL和C语言多线程的DB2 workload开发

由于程序示例代码的重用性较高,可以大大的提高需要使用这种 DB2 workload 的软件http://www.aliyun.com/zixun/aggregation/18863.html">自动化测试人员,使用 C 语言多线程访问 DB2 的软件开发人员的工作效率. 众所周知,在使用 DB2 数据库的实际生产环境中, 我们会遇到各种各样的应用,例如基于不同的开发语言,基于不同的体系架构或者基于不同的数据库连接方式等等.针对这些不同的 workload, 我们从事 DB2 性能监控工具测

基于Huffman编码的C语言压缩和解压缩文件程序

问题描述 基于Huffman编码的C语言压缩和解压缩文件程序 基于Huffman编码的C语言解压缩和解压缩文件程序文件程序. c功底比较差...一下午只写出了huffman树. 想求能直接调试的代码.最好有注释. 解决方案 基于Huffman编码的C语言解压缩文件程序Huffman 编码压缩 解决方案二: http://www.linuxidc.com/Linux/2014-08/105672.htm 解决方案三: 为什么不用自适应算数编码呢?效果要比霍夫曼好多了吧! 解决方案四: 为什么不用自

VB语言一个关于字符串组合的程序

问题描述 VB语言一个关于字符串组合的程序 这样的数字构成的字符串在VB中怎么穷举? 12*5* 输出12051 12052 ... 12959 解决方案 for i = 0 to 9 for j = 0 to 9 print "12" & i & "5" & j next next

visual studio 2010-vs2010用C语言为什么连接不上mysql

问题描述 vs2010用C语言为什么连接不上mysql MYSQL *mysql;mysql=mysql_init(NULL);if(!mysql_real_connect(mysqllocalhost""root""0412qwer""xs""3306NULL0)) AfxMessageBox(_T(""数据库连接失败""));else{AfxMessageBox(_T("&

linux下基于C语言的信号编程实例_C 语言

本文实例讲述了linux下基于C语言的信号编程方法.分享给大家供大家参考.具体如下: #include <stdio.h> #include <unistd.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> void sig_handler(int sig_no, siginfo_t *info, void *ctext){ printf("receive si

浅谈C++对象组合_C 语言

#include<stdio.h> //初始化列表 提供了对成员变量初始化的方式 //Constructor class M { private: int mI; public: M(int i) { printf("M(int i),i=%d\n",i); mI=i; } int getI() { return mI; } }; class Test { private: const int c; //类里面成员定义时变量不能初始化 M m1; M m2; public:

c语言 结构体函数:PHP的语言结构和函数的区别

相信大家经常看到对比一些PHP应用中,说用isset() 替换 strlen(),isset比strlen执行速度快等.例子: if ( isset($user) ) { //do some thing }原因是isset是语言结构,而strlen是一个函数.还有echo 是个语言结构,不是个函数.那什么是语言结构呢?它和函数有什么不同吗?1. 什么是语言结构和函数语言结构:就是PHP语言的关键词,语言语法的一部分:它不可以被用户定义或者添加到语言扩展或者库中:它可以有也可以没有变量和返回值.函

Win10 UWP 开发系列:使用多语言工具包让应用支持多语言

原文:Win10 UWP 开发系列:使用多语言工具包让应用支持多语言 之前我在一篇blog中写过如何使用多语言工具包,见http://www.cnblogs.com/yanxiaodi/p/3800767.html 在WinEcos社区也发布过一篇详细的文章介绍多语言工具包的使用,但因社区改版那篇文章已经找不到了. 当时写的时候还没有出Win10的SDK,都是基于UAP框架写的.微软早已经发布了Win10的SDK,相应的项目结构也发生了变化,以前分为两个项目通过Share项目共享代码的方式被抛弃