一、声明接口

 type Result interface {
LastInsertId() (int64, error)
RowsAffected() (int64, error)
}

二、实现接口,这里却将接口作为成员变量,进而将接口的实现转换为接口的调用,仅仅是封装了接口,实际上并没有真的实现,而是坐等别人去实现

 //    一把锁
// 一个结果集的假接口实现,表示需要的功能,让他人来具体实现。假装实现了某个接口,其实是调用了内部接口的对应方法
type driverResult struct {
sync.Locker
resi driver.Result
}
// Result 是对已执行 SQL 命令的总结,。
// LastInsertId() 会返回一个由数据库生成的整数, 这个整数是对命令的响应。 在插入一个新的数据行时, 这个整数通常来源于数据表中的自增数据列。
// 并不是所有数据库都支持这个特性, 并且各个数据库在实现这个特性时使用的语句也会有所不同。
// RowsAffected() 返回受到更新、插入或者删除操作影响的行数量, 并不是所有数据库或者所有数据库驱动都支持这个特性。
type Result interface {
LastInsertId() (int64, error)
RowsAffected() (int64, error)
} func (dr driverResult) LastInsertId() (int64, error) {
dr.Lock()
defer dr.Unlock()
return dr.resi.LastInsertId()
} func (dr driverResult) RowsAffected() (int64, error) {
dr.Lock()
defer dr.Unlock()
return dr.resi.RowsAffected()
}

Go 中的 interface 是一种类型,更准确的说是一种抽象类型 abstract type,一个 interface 就是包含了一系列行为的 method 集合,interface 的定义很简单:

 package io

 type Writer interface {
Write(p []byte) (n int, err error)
}

如果一个 concrete type 实现了某个 interface,我们说这个 concrete type 实现了 interface 包含的所有 method,必须是所有的 method。Go 中的 interface 不同于其它语言,它是隐式的 implicitly,这意味着对于一个已有类型,你可以不用更改任何代码就可以让其满足某个 interface。

在 Go 的标准库 fmt 中有一系列的方法可以很好的诠释 interface 是如何应用到实践当中的。

 package fmt

 func Fprintf(w io.Writer, format string, args ...interface{}) (int, error)

 func Printf(format string, args ...interface{}) (int, error) {
return Fprintf(os.Stdout, format, args...)
} func Sprintf(format string, args ...interface{}) string {
var buf bytes.Buffer
Fprintf(&buf, format, args...)
return buf.String()
}

在 Printf 函数中,调用 Fprintf 时指定的输出是标准输出,这正是 Printf 的功能:Printf formats according to a format specifier and writes to standard output,根据指定的格式化要求输出到标准输出,os.Stdout 的类型是 *os.File 。Fprintf 中的前缀 F 表示 File,意思是格式化的输出被输出到函数指定的第一个 File 类型的参数中。

同样在 Sprintf 函数中,调用 Fprintf 时指定的输出是一个指向某个 memory buffer 的指针,其类似一个 *os.File

虽然 bytes.Buffer 和 os.Stdout 是不同的,但是它们都可以被用于调用同一个函数 Fprintf,就是因为 Fprintf 的第一个参数是接口类型 io.Writer ,而 bytes.Buffer 和 os.Stdout 都实现了这个 interface,即它们都实现了 Write 这个 method,这个 interface 并不是一个 File 却完成了类似 File的功能。

Fprintf 其实并不关心它的第一个参数是一个 file 还是一段 memory,它只是调用了 Write method。这正是 interface 所关注的,只在乎行为,不在乎其值,这种能力让我们可以非常自由的向 Fprintf 传递任何满足 io.Writer 的 concrete type,这是 Go interface 带来的 substitutability 可替代性,object-oriented programming 的一种重要特性。

看个例子:

 package main

 import (
"fmt"
) type ByteCounter int func (c *ByteCounter) Write(p []byte) (int, error) {
*c += ByteCounter(len(p)) // convert int to ByteCounter
return len(p), nil
} func main() { var c ByteCounter
c.Write([]byte("hello"))
fmt.Println(c) // 5 #1
fmt.Fprintf(&c, "hello") #2
fmt.Println(c) // 10 #3
}


这就是 Go 中的 interface 所具有的最基本的功能:作为一种 abstract type,实现各种 concrete type 的行为统一。ByteCounter
 实现了 Write method,它满足 io.Writer interface,Write method 计算传给它的 byte slice 的长度并且赋值给自身,所以 #1 输出到标准输出的是它的值 5,正如前文所言,调用 fmt.Fprintf 时再次调用了 c 的 Write method,所以 #3 输出是 10。

golang接口的封装的更多相关文章

  1. Golang 接口与反射知识要点

    目录 Golang 接口与反射知识要点 1. 接口类型变量 2. 类型断言 3. 鸭子类型 4. 反射机制 5. reflect 包 TypeOf().ValueOf() Type().Kind() ...

  2. Golang 接口

    1 接口是什么 Golang中没有像Python.Java拥有类和对象的概念,其封装对象或说明对象是通过接口来实现的.比如谁能够实现什么样的功能,便能够将其抽象化封装. 接口定义了一组方法(抽象方法集 ...

  3. C#开发微信门户及应用(23)-微信小店商品管理接口的封装和测试

    在上篇<C#开发微信门户及应用(22)-微信小店的开发和使用>里面介绍了一些微信小店的基础知识,以及对应的对象模型,本篇继续微信小店的主题,介绍其中API接口的封装和测试使用.微信小店的相 ...

  4. <<海闻电子发票接口 ESB 封装 代码指示 文档>>

    <<海闻电子发票接口 ESB 封装 代码指示 文档>> isValid 是否有效标志 代码 中文 说明 true 成功 false 失败   code 海闻错误说明 代码 中文 ...

  5. <<海闻电子发票接口 ESB 封装文档>>

    <<海闻电子发票接口 ESB 封装文档>> 章节目录结构: 发票验证接口 发票开具接口 ESB请求地址: 发票验证接口: http://10.15.22.120:8866/42 ...

  6. 微信公众平台消息接口开发-封装weixin.class.php

    原文:微信公众平台消息接口开发-封装weixin.class.php 一.封装weixin.class.php 由于微信公众平台的通信使用的是特定格式的XML数据,每次接受和回复都要去做一大堆的数据处 ...

  7. 【Golang 接口自动化06】微信支付md5签名计算及其优化

    前言 可能看过我博客的朋友知道我主要是做的支付这一块的测试工作.而我们都知道现在比较流行的支付方式就是微信支付和支付宝支付,当然最近在使用低手续费大力推广的京东金融(已改名为京东数科)以后也可能站到第 ...

  8. 【Golang 接口自动化00】为什么要用Golang做自动化?

    为什么使用Golang做自动化 顺应公司的趋势学习了Golang之后,因为没有开发那么多的时间和项目来实践,怕步此前学习Java缺少练习遗忘殆尽的后尘,决定利用工作之余的时间把此前用Python的写的 ...

  9. 接口API封装中常见的HTTP状态码

    在进行后端接口API封装的过程中,需要考虑各种错误信息的输出.一般情况下,根据相应问题输出适合的HTTP状态码,可以方便前端快速定位错误,减少沟通成本. HTTP状态码有很多,每个都有对应的含义,下面 ...

随机推荐

  1. [WPF自定义控件]?使用WindowChrome自定义Window Style

    原文:[WPF自定义控件]?使用WindowChrome自定义Window Style 1. 为什么要自定义Window 对稍微有点规模的桌面软件来说自定义的Window几乎是标配了,一来设计师总是克 ...

  2. 简单搭建dubbo

    为什么要用dubbo? 当网站规模达到了一定的量级的时候,普通的MVC框架已经不能满足我们的需求,于是分布式的服务框架和流动式的架构就凸显出来了.     单一应用架构 当网站流量很小时,只需一个应用 ...

  3. SSM三大框架的运行流程、原理、核心技术详解

    一.Spring部分1.Spring的运行流程第一步:加载配置文件ApplicationContext ac = new ClassPathXmlApplicationContext("be ...

  4. 记mysql 启动不了了的解决方法

    系统: centos7 本地的环境,mysql启动不了,查看 /var/log/mysqld.log 有以下内容 2018-12-24T08:05:38.090527Z 0 [Warning] TIM ...

  5. [记录]Wdinwos scikit-learn 安装

    安装的软件有: Python: 3.6.0 numpy-1.11.3+mkl-cp36-cp36m-win_amd64.whl(全名) scipy-0.19.0-cp36-cp36m-win_amd6 ...

  6. 简单搭建 @vue-cli3.0 及常用sass使用

    1,在安装了Node.js后使用其中自带的包管理工具npm.或者使用淘宝镜像cnpm(这里不做说明) 1-1,下载vue3.0脚手架(如果之前装vue-cli3x之前的版本,先卸载 npm unins ...

  7. Chrome快捷键, Mac 下 Chrome 浏览器 快捷键

    Chrome窗口和标签页快捷键:Ctrl+N 打开新窗口 Ctrl+T 打开新标签页 Ctrl+Shift+N 在隐身模式下打开新窗口 Ctrl+O,然后选择文件 在谷歌浏览器中打开计算机上的文件 按 ...

  8. iOS开发CoreData的简单使用

    1.简介 CoreData是iOS5后,苹果提供的原生的用于对象化管理数据并且持久化的框架.iOS10苹果对CoreData进一步进行了封装,而且效率更高!相关类的简单介绍: NSManagedObj ...

  9. SPSS分析技术:多元方差分析

    SPSS分析技术:多元方差分析 下面要介绍多元方差分析的内容,多元方差分析是研究多个自变量与多个因变量相互关系的一种统计理论方法,又称多变量分析.多元方差分析实质上是单因变量方差分析(包括单因素和多因 ...

  10. 关于前端调用后端php数据跨域的问题

    https://blog.csdn.net/qq_21386275/article/details/87269979 js前端 <!DOCTYPE html><html>< ...