不一样的go语言-玩转语法之一
这段时间为俗事所累,疲以应付,落下了不少想法,错过了更新的日子。这个专题开始之际,已经准备了不下十几个主题,而在写作的过程中,又有新想法与主题涌现出来。未来预计想写写的内容主要包括:
- 玩转语法系列
- Context的来龙去脉
- 函数、闭包与范畴论的关系
- 线程与协程之争
- 通道的那些事
今天的玩转语法系列,先起个头,调子稍微低一点,主要想与大家分享一下go语言在实践中的优美之处。用不同的语言来解决相同的问题,最能直观感受语言的魅力。
先来看看一版java代码的例子(这里没有贬低java的意思,仅仅是举个例子,java是一门很实用的语言):
public class Tea {
//名称
private String name;
//奶
public boolean milk;
//珍珠
public boolean pearl;
//冰
public boolean ice;
public String toString() {
return name.concat(", ")
.concat("milk: ")
.concat(String.valueOf(milk))
.concat(", pearl: ")
.concat(String.valueOf(pearl))
.concat(", ice: ")
.concat(String.valueOf(ice));
}
}
public class HeyTeaMaker {
public Tea make(String name, boolean milk, boolean pearl, boolean ice) {
Tea tea = new Tea();
tea.name = name;
tea.milk = milk;
tea.pearl = pearl;
tea.ice = ice;
return tea;
}
}
public static void main(String[] args) {
HeyTeaMaker maker = new HeyTeaMaker();
Tea tea = maker.make("HeyTea", true, true, false);
System.out.println("tea: " + tea);
}
上面的代码如果不加以设计,直接以这样的方式编写,那么如果需要给茶增加一个属性,比如糖,带来的修改是灾难性的,不单Tea、HeyTeaMake要修改,所有使用的地方都要修改。当然花一番心思设计一下,比如使用建造者模式包装一下。老话说,拥抱变化,java也是可以很优美的。
在这个例子中,其实茶的配料都是可选,但因为java天生没有可选参数,参数亦没有默认值,因而对于这个例子恰巧是java的弱项。而使用go就简洁多了,比如:
package main
import "fmt"
func main() {
fmt.Println(NewTea("HeyTea", AddMilk(), AddPearl()))
}
type Tea struct {
Name string
Milk bool
Pearl bool
Ice bool
}
func NewTea(name string, option ... TeaOption) *Tea {
tea := &Tea{Name: name}
for _, o := range option {
o(tea)
}
return tea
}
func (t *Tea) String() string {
return fmt.Sprintf("%s, milk: %t, pearl: %t, ice: %t", t.Name, t.Milk, t.Pearl, t.Ice)
}
type TeaOption func(t *Tea);
func AddMilk() TeaOption {
return func(t *Tea) {
t.Milk = true
}
}
func AddPearl() TeaOption {
return func(t *Tea) {
t.Pearl = true
}
}
func AddIce() TeaOption {
return func(t *Tea) {
t.Ice = true
}
}
go其实也没有可选参数,参数也不允许有默认值,但因为函数与闭包的配合使用,使得go很轻松,很简洁地就解决了问题。即使要给茶增加一个属性糖,只需修改Tea,并且加一个AddSugar方法即可,调用的地方如果不需要糖,就不用修改。
java8已经引入了lamba与FunctionalInterface,其实完全依照go的实现,java也是可以写出类似的代码来。比如:
import java.util.function.Function;
public class Tea {
//名称
private String name;
//奶
public boolean milk;
//珍珠
public boolean pearl;
//冰
public boolean ice;
public String toString() {
return name.concat(", ")
.concat("milk: ")
.concat(String.valueOf(milk))
.concat(", pearl: ")
.concat(String.valueOf(pearl))
.concat(", ice: ")
.concat(String.valueOf(ice));
}
public static Function<Tea, Void> addMilk() {
return (Tea t)-> {
t.milk = true;
return null;
};
}
public static Function<Tea, Void> addPearl() {
return (Tea t)-> {
t.pearl = true;
return null;
};
}
public static Function<Tea, Void> addIce() {
return (Tea t)-> {
t.ice = true;
return null;
};
}
public static Tea newTea(String name, Function<Tea, Void> ...option) {
Tea tea = new Tea();
tea.name = name;
for (Function<Tea, Void> item : option) {
item.apply(tea);
}
return tea;
}
public static void main(String[] args) {
Tea tea = newTea("HeyTea", addIce(), addMilk(), addPearl());
System.out.println("tea: " + tea);
}
}
功能倒是实现了,但感觉看起来仍然没有go好,一种妙不可言,只可意会不可言传的感觉。
欢迎关注个人公众号

不一样的go语言-玩转语法之一的更多相关文章
- 不一样的go语言-玩转语法之二
本文继续玩转语法,是为之二. I/O(Input/Output),输入输出是计算机最为突出的特点,也可以说是计算机最为核心的功能.没有I/O,计算机就是一堆废铜废铁.从最低层的电子元器件开始, ...
- C语言-01-基本语法
一.学前需知 开发工具 windows平台:Visual C++6.0等 mac平台:Xcode6.0等 以下文章内容皆是以Xcode6.0为开发工具,clang编译器. Xcode的一些常用快捷键 ...
- 关于JS脚本语言的基础语法
JS脚本语言的基础语法:输出语法 alert("警告!"); confirm("确定吗?"); prompt("请输入密码");为弱 ...
- Xamarin XAML语言教程基础语法篇大学霸
Xamarin XAML语言教程基础语法篇大学霸 前 言 Xamarin是一个跨平台开发框架.它可以用来开发iOS.Android.Windows Phone和Mac的应用程序.使用Xamarin框 ...
- Cocos2d-x 脚本语言Lua基本语法
Cocos2d-x 脚本语言Lua基本语法 前面一篇博客对Lua这门小巧的语言进行了简单的介绍.本篇博客来给大家略微讲一下Lua的语法.不会长篇累牍得把Lua的全部语法都讲一遍,这里通过下面几点来讲L ...
- GO语言的基本语法之变量,常量,条件语句,循环语句
GO语言的基本语法之变量,常量,条件语句,循环语句 作为慕课网得笔记自己看 定义变量: 使用var关键字 var a, b, C bool var s1, s2 string = "hell ...
- tn文本分析语言(二) 基本语法
tn是desert和tan共同开发的一种用于匹配,转写和抽取文本的语言.解释器使用Python实现,代码不超过1000行. 本文主要介绍tn的基本语法.高级内容可以参考其他篇章.使用这样的语法,是为了 ...
- (转)JavaScript二:JavaScript语言的基本语法要求
摘自:http://blog.csdn.net/erlian1992 要学习好JavaScript,首先我们要懂JavaScript语言的一些基本语法要求: 一,区分大小写 JavaScript语言区 ...
- javaweb学习总结七(XML语言作用、语法)
一:XML语言的概念以及作用 1:xml概念:extensible Markup language,可扩展行标记语言,因为html的语法比较混乱,不够严谨. 用html写的系统不好维护,所以w3c组织 ...
随机推荐
- 常用方法 DataTable转换为Entitys
备注:摘自网上 有附地址 public static List<T> DataTableToEntities<T>(this DataTable dt) where T : c ...
- AtCoder Regular Contest 069 F Flags 二分,2-sat,线段树优化建图
AtCoder Regular Contest 069 F Flags 二分,2-sat,线段树优化建图 链接 AtCoder 大意 在数轴上放上n个点,点i可能的位置有\(x_i\)或者\(y_i\ ...
- 第04组alpha冲刺(3/4)
队名:斗地组 组长博客:地址 作业博客:Alpha冲刺(3/4) 各组员情况 林涛(组长) 过去两天完成了哪些任务: 1.收集各个组员的进度 2.写博客 展示GitHub当日代码/文档签入记录: 接下 ...
- Flume 实战,将多台机器日志直接收集到 Kafka
目前我们使用的一个 b 端软件的报错日志分散在集群各处,现在想把它收集到一个地方然后统一丢进 Kafka 提供给下游业务进行消费. 我想到了 flume,之前让同事搭建的这次自己想多了解一些细节于是就 ...
- 运行java程序的时候出现Exception in thread "main" java.lang.UnsupportedClassVersionError:
1 Exception in thread "main" java.lang.UnsupportedClassVersionError: com/test/inherited/In ...
- UDF——涡量
用涡量的模来显示涡结构是一种很常用的方法 涡量: 针对二维,涡量场表示为如下的标量: 对于二维流动来说,涡量为正,表示逆时针旋转:涡量为负,表示顺时针旋转 三维涡量: 其中: 计算涡量的模: 二维涡量 ...
- Java finally未被执行的情况
一种是先执行了用于终止程序的System.exit()方法,或进程被关闭 还有一种情况是,当前线程一直在执行,在一些业务逻辑里面跳不出来,看上去就像finally一直未被执行 线程被终止的时候也会执行 ...
- 利用python实现汉字转拼音
安装:pip install pypinyin import pypinyin # 不带声调的(style=pypinyin.NORMAL) def pinyin(word): s = '' for ...
- Kibana数据可视化
Kibana数据可视化 1,3.1使用logstash导入数据的问题 会出现错误提示: [location] is defined as an object in mapping [doc] but ...
- jsch配置sftp服务器ssh免密登录
前期对接了一个通过ssh免密登录的需求,是基于原先密码登录sftp服务器的代码上进行改造,实际上代码改动量非常少,趁此机会对自己整理的资料做一下总结. 1. 什么是SFTP SFTP是一个安全文件传送 ...