不一样的go语言-玩转语法之二
本文继续玩转语法,是为之二。
I/O(Input/Output),输入输出是计算机最为突出的特点,也可以说是计算机最为核心的功能。没有I/O,计算机就是一堆废铜废铁。从最低层的电子元器件开始,计算机科学家与工程师们,就一直奔跑在追求卓越的I/O性能的道路上。计算机每一次大跨越,就是一次I/O的脱胎换骨。从机械时代到电子管,到晶体管,再到集成电路,再到未来的量子时代,无不预示着I/O对于计算机科学的重要性。但这只是最基础的I/O层,在这之上,又有更多层次抽象,比如内存、磁盘、网络;更多的I/O表现形式,比如文件、数据库、键鼠、显示器、打印机等等。“一切皆是文件”,这是Unix/Linux的基本哲学之一,从这个角度看,即一切皆I/O。
底层设计是如此,那么在高层设计,仍然是如此。从各个语言对于I/O的实现来看,无不将I/O置于重中之重的地方,从I/O的设计中,可大致看出一个语言的设计哲学与理念。比如java中有大量的类名包含stream,强调流的概念;而golang则没有出现这个词,更强调的是byte,即字节。从所有即文件的角度来看,字节更直观地对应到文件中的内容。而java则又进行了一次抽象,相当于将很多的字节看作是连续的字节流,同时对流提供了更多的操作方法,如flip、mark等。
在Java中,I/O相关的SDK使用了大量的装饰器与适配器模式。装饰器模式其实是对原有类作功能增强的一种方法,而适配器则是将非同类型的东西变为同类型的东西。比如StringReader即是适配器类,它实现了流对象接口Reader。它的功能是将非流对象String适配为流对象。旧版SDK还有一个叫StringInputStream的类,它也是适配器类。适配器与装饰器详解如下:
项 | 用途 | 参与对象 | jdk示例 |
---|---|---|---|
装饰器 | 功能增强 | 两个或以上相同类型的类 | BufferedInputStream, 可用于装饰其他的InputStream子类 |
适配器 | 类型转换(适配) | 两个不同类型的类 | StringReader, 将String转换(适配)为Reader类型 |
而在go语言中,I/O也大量采用这样的设计方式。比如:
项 | 相关类 | 示例 |
---|---|---|
装饰器 | MultiReader, MultiWriter, bufio.Reader, bufio.Writer, bufio.Scanner, LimitReader, TeeReader | - |
适配器 | string.Reader, bytes.Reader | ex: strings.NewReader("test") |
装饰器与适配器的使用,使得go库的设计大为简化,并且因此而产生无比的灵活性与扩展性,开发者可以自行设计新的装饰器、适配器完成开发任务。
那么,在实际的开发过程中,装饰器与适配器还有哪些妙用呢?在前面讲述的例子中,这两者是应用在interface与struct的层面,其实在go语言中,两者更妙的应用是与func的结合,可以带来新鲜、意想不到的体验。比如:
package main
import "fmt"
func greet(name string) {
fmt.Printf("Hello %s!\n", name)
}
func decorateGreet(f func(string), name string) {
fmt.Println("before greet")
f(name)
fmt.Println("after greet")
}
func main() {
decorateGreet(greet, "John")
}
虽然这个例子有点丑陋,但这真的是装饰器的应用。尽管java的经验告诉我们,面向切面编程使用的应该是代理模式(静态代理或者动态代理),甚至要动用反射、ASM,但其实使用装饰器更直接。当然为了装一下逼,通常不会写上面那么直白的代码。
package main
import "fmt"
func greet(name string) {
fmt.Printf("Hello %s!\n", name)
}
func decorateGreet(f func(string)) func(string) {
return func(name string) {
fmt.Println("before greet")
f(name)
fmt.Println("after greet")
}
}
func main() {
decorateGreet(greet)("装逼John")
}
调用方式变了一下,档次一下升高了不知多少。这样看起来才能让人相信:我真的是在用装饰器。很显然,装饰器起到一个功能增强的作用,从代码上看,无非就是接受A类型的对象(函数也是对象),然后返回A类型的对象,而在返回类型的实现中触发入参,同时加一些功能增强的代码。
对于适配器来说,使用它想当于做了一次类型强转,如下面的示例尝试将hi函数适配成greet函数。
package main
import "fmt"
type hi func()
type greet func(string)
func sayHi() {
fmt.Printf("Hi")
}
func toGreet(h hi) greet {
return func(name string) {
h()
fmt.Printf(", %s", name)
}
}
func main() {
toGreet(sayHi)("John")
}
当函数是一等公民的时候,一切看起来都是那么地自然顺畅,而类似的功能用java来实现,就必须提高到类的层面了。
欢迎关注个人公众号
不一样的go语言-玩转语法之二的更多相关文章
- 不一样的go语言-玩转语法之一
这段时间为俗事所累,疲以应付,落下了不少想法,错过了更新的日子.这个专题开始之际,已经准备了不下十几个主题,而在写作的过程中,又有新想法与主题涌现出来.未来预计想写写的内容主要包括: 玩转语法系列 ...
- Go语言的基本语法(二)
一·if -else (1) package main import "fmt" // if - else //func main(){ // // 先定义 一个变量 // v ...
- C语言-01-基本语法
一.学前需知 开发工具 windows平台:Visual C++6.0等 mac平台:Xcode6.0等 以下文章内容皆是以Xcode6.0为开发工具,clang编译器. Xcode的一些常用快捷键 ...
- 关于JS脚本语言的基础语法
JS脚本语言的基础语法:输出语法 alert("警告!"); confirm("确定吗?"); prompt("请输入密码");为弱 ...
- R语言语法基础二
R语言语法基础二 重塑数据 增加行和列 # 创建向量 city = c("Tampa","Seattle","Hartford"," ...
- 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 ...
- Python 十大装 X 语法(二)
Python 是一种代表简单思想的语言,其语法相对简单,很容易上手.不过,如果就此小视 Python 语法的精妙和深邃,那就大错特错了.本文精心筛选了最能展现 Python 语法之精妙的十个知识点,并 ...
随机推荐
- Computer system with dual operating modes
A system switches between non-secure and secure modes by making processes, applications, and data fo ...
- Etag & If-None-Match 专题
一.概述 缓存通俗点讲,就是将已经得到的‘东东’存放在一个相对于自己而言,尽可能近的地方,以便下次需要时,不会再二笔地跑到起始点(很远的地方)去获取,而是就近解决,从而缩短时间和节约金钱(坐车要钱嘛) ...
- Java反射获取内部类有局限
这周接触到继承及修改具有包访问权的内部类内容,略梳理了下各种资料,发觉在包外修改内部类内容必须通过实例....... 网上关于这部分的内容比较少,参考了下这位的帖子:http://blog.csdn. ...
- 使用XCA(X Certificate and key management)可视化项目经理SSL 凭证(4)--凭借自身的凭证管理中心的定义(Certificate Authority)签名证书申请
随着XCA(X Certificate and key management)可视化项目经理SSL 证书系列文章(2)和(3)中.我们学习了怎样用XCA(X Certificate and key m ...
- hdu4360 spfa+分割点
标题要求必须按照L O V E 行走为了,你必须至少有一个完整的LOVE.说明可以通过同一个点反复 对每一个点拆分为4个点.分别为从L,O,V,E到达. 起始点看做是从E到达的 spfa时发现当前点距 ...
- 在IIS上部署.net core的webapi项目 以及502.5错误的两种解决方法
首先要在服务器上面安装.net core https://github.com/dotnet/core/tree/master/release-notes/download-archives 这里面有 ...
- 【值转换器】 WPF中Image数据绑定Icon对象
原文:[值转换器] WPF中Image数据绑定Icon对象 这是原来的代码: <Image Source="{Binding MenuIcon}" ...
- Goutte 获取http response
$client = new Goutte\Client(); $crawler = $client->request('GET', 'http://symfony.com'); 获取http 响 ...
- 使用aws和tomcat搭建服务器过程中的一些坑.
在国外没啥事做, 考前也不愿意复习, 看到aws能免费试用一年, 于是就试着搞了搞, 就准备搭建个个人网站玩玩. aws的注册与创建实例 首先个人感觉这个东西使用起来还是很方便的, 一开始注册完验证完 ...
- windows服务的编写,手动安装与卸载
windows服务的编写 1.要添加的引用 using System.ServiceProcess; using System.ServiceModel ; using WcfServiceLibra ...