再golang中,我们要充分理解interface和struct这两种数据类型。为此,我们需要优先理解type的作用。

type是golang语言中定义数据类型的唯一关键字。对于type中的匿名成员和指针成员,这里先不讲,重点讲解interface和struct这两种特殊的数据类型。

interface和struct也是数据类型,特殊在于interface作为万能的接口类型,而struct作为常用的自定义数据类型的关键字。说到这里相比大家已经明白interface的侧重点在于接口的定义(方法),而struct侧重点在于数据结构的定义。使用struct定义了数据结构,可以直接使用func方法定义数据结构中使用的方法。但是为了解耦,为了扩展,一般在真正设置功能性函数时,除了内置的数据类型外,都推荐使用接口的方法来传递相关方法。

既然推荐使用接口的方法来作为参数,那么具体结构中的数据成员又如何访问呢?golang提供了非常方便的类型查询和类型转换方法。名称.(type)用于类型查询,名称.(具体类型)用于类型转换。因此,使用接口作为函数参数是很有价值的。

另外,我们还需要明白对象和对象指针在golang中的微妙处理,golang可以自动将对数据类型定义的方法抓转换成对数据类型指针定义的方法。但不能自动的将对数据类型指针的方法转换为对数据类型定义的方法。

以下是我们的测试程序,注释已经注明了相关说明。

package main

import "fmt"

//定义一个接口
type Stryc interface {
Int() int
} //定义一个自定义数据类型
type myCls struct {
value int
}
//使用数据类型指针绑定方法(在调用方法时,数据类型在golang中会默认转换为数据类型指针进行使用)
func(a * myCls) Int() int{
return a.value
}
//定义一个函数,参数为一个自定义的数据类型
func printTheValueByStruct(arg myCls){
fmt.Printf("the value is %d \n",arg.Int())
}
//定义一个函数,参数为一个接口
func printTheValue(arg Stryc) int{
fmt.Printf("the value is %d \n",arg.Int()/*使用接口调用接口的方法*/)
return arg.Int()
} //定义一个函数,参数为动态个数的接口类型参数
func printAnyValue(args ...interface{}){
//使用for range方法获取每一个接口
for _,arg := range args{
//使用.(type)方法查询接口的数据类型
switch arg.(type) {
case int:
fmt.Println("the type is int")
case string:
fmt.Println("the type is string")
case myCls:/*是自定义数据类型*/
//使用.(数据类型)进行强转
var b myCls = arg.(myCls)
fmt.Println("the type is myCls, the function value is ", b.Int()/*d调用数据类型的方法,golang会转换为数据指针类型调用*/,"the struct value is ", b.value/*调用数据结构的数据*/)
case Stryc:/*是定义的接口数据类型*/
fmt.Println("the type is Stryc interface, the function value is ", arg.(Stryc).Int()/*将接口强转到指定接口,并调用方法*/)
}
}
} func main(){
var V1 *myCls = new(myCls) //创建一个对象指针
V1.value = 1111111 //给对象赋值
var V2 myCls = myCls{222222222} //创建一个对象,给对象赋值
var a interface {}=myCls{33333} //创建一个对象,将对象赋值后传给一个万能类型接口
var a1 interface{}=&myCls{444444}//创建一个对象,将对象指针传给一个万能类型接口
fmt.Println("hello world!") printTheValue(V1) //V1会转换为Stryc接口被调用其中的方法
printTheValue(a1.(Stryc)) //万能接口a1中放置的对象指针被强制转为Stryc接口调用
printTheValueByStruct(*V1) //强制将V1的对象使用*显示传入函数,因为参数是对象
printTheValueByStruct(a.(myCls))//强制将万能接口a中放置的对象转换为对象传入函数,因为参数是对象 printTheValue(&V2) //将对象的指针传入函数,golang将其转换为Stryc接口
printAnyValue(V1/*传入一个指针,会同Stryc接口数据类型匹配*/,
V2/*传入一个对象,会同myCls数据类型匹配*/,
*V1/*将指针显示为对象传入,会同myCls数据类型匹配*/,
&V2/*将对象的指针传入,会同Stryc接口数据类型匹配*/)
}

以下是执行结果

hello world!
the value is
the value is
the value is
the value is
the value is
the type is Stryc interface, the function value is
the type is myCls, the function value is the struct value is
the type is myCls, the function value is the struct value is
the type is Stryc interface, the function value is

golang中接口interface和struct结构类的分析的更多相关文章

  1. 【荐】详解 golang 中的 interface 和 nil

    golang 的 nil 在概念上和其它语言的 null.None.nil.NULL一样,都指代零值或空值.nil 是预先说明的标识符,也即通常意义上的关键字.在 golang 中,nil 只能赋值给 ...

  2. java中接口interface可以持有多个类的共享常量

    3.接口持有多个类的共享常量  接口另一主要功能,马克-to-win: 可以使用接口来引入多个类的共享常量.所有的这些变量名都将作为常量看待.所有定义在接口中的常量都默认为public.static和 ...

  3. 七、golang中接口、反射

    一.接口定义 1.定义 interface类型可以定义一组方法,但是这些不需要实现,并且interface不能包含任何变量 package main import ( "fmt" ...

  4. Go语言的接口interface、struct和组合、继承

    Go语言的interface概念相对于C++中的基类,通过interface来实现多态功能. 在C++中,当需要实现多态功能时,步骤是首先定义一个基类,该基类使用虚函数或者纯虚函数抽象了所有子类会用到 ...

  5. java中接口interface和private私有内部类怎样一块配合着用?

    3.接口interface和private内部类协同工作[新手可忽略不影响继续学习]马克-to-win:由于是private内部类,外面无法访问甚至无法看到你编的源代码(如果在不同的包中),非常安全. ...

  6. golang中接口详解

    package main import ( "fmt" ) type Sayer interface { say() } type Mover interface { move() ...

  7. golang中接口对象的转型

    接口对象的转型有两种方式: 1. 方式一:instance,ok:=接口对象.(实际类型) 如果该接口对象是对应的实际类型,那么instance就是转型之后对象,ok的值为true 配合if...el ...

  8. golang中接口类型小案例

    1.  在项目中实现注册成功之后,向用户发送邮件.微信提醒 package main import "fmt" type IMessage interface { send() b ...

  9. java中接口interface有什么用呢?举例!

    接口只有方法的定义,没有方法的任何实现.那这有什么意义呢?马克-to-win: 接口就像一个服务合同.接口只关心必须得干什么而不关心如何去实现它.有 意义吗?有意义.马克-to-win:比如我们的软件 ...

随机推荐

  1. Python学习笔记(二十五)操作文件和目录

    摘抄:https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014319253241 ...

  2. Python print "hello world" SyntaxError: invalid syntax

    刚安装Python,在IDLE中输入print “Hello World”,谁知却发生错误: >>> print "Hello World"SyntaxError ...

  3. ① 设计模式的艺术-01.单例(Singleton)模式

    单例模式为何要出现 在工作过程中,发现所有可以使用单例模式的类都有一个共性,那就是这个类没有自己的状态,换句话说,这些类无论你实例化多少个,其实都是一样的. 如果我们不将这个类控制成单例的结构,应用中 ...

  4. MagicB.0—怎样设置电脑自动关机?

    天太晚了,该睡觉了,可是你的东西也许正在下载,软件正在更新,总之电脑还有一些工作没有完成,又不需要你人为的守着,随他去吧!可是电脑已经工作了一天了,它也要休息一下,再者也不能浪费电力资源呀,那么就来使 ...

  5. 【BZOJ】2243 [SDOI2011]染色

    [算法]树链剖分+线段树 [题解] 树链剖分算法:http://www.cnblogs.com/onioncyc/p/6207462.html 定义线段树结构体有l,r,lc,rc,sum,data. ...

  6. composer 上提交自己的包

    先在github上复制自己的地址在 https://packagist.org/packages/submit ->check->submit

  7. NYOJ 328 完全覆盖 (找规律)

    题目链接 描述 有一天小董子在玩一种游戏----用21或12的骨牌把mn的棋盘完全覆盖.但他感觉游戏过于简单,于是就随机生成了两个方块的位置(可能相同),标记一下,标记后的方块不用覆盖.还要注意小董子 ...

  8. phinx:php数据库迁移

    Phinx使你的php app进行数据迁移的过程变得异常轻松,在五分钟之内你就可以安装好Phinx 并进行数据迁移. 特性 使用php代码进行数据迁移 部署模式下迁移 五分钟之内使用 不再担心数据库的 ...

  9. 千字短文解决工程师们关于SPI的迷糊!

    串行外设接口 (SPI) 总线是一个工作在全双工模式下的同步串行数据链路.它可用于在单个主控制器和一个或多个从设备之间交换数据.其简单的实施方案只使用四条支持数据与控制的信号线(图 1): 图1:基本 ...

  10. Linux内核中的Cache段

    Linux内核中的Cache段 原文地址:http://blogold.chinaunix.net/u2/85263/showart_1743693.html 最近移植LEON3的内核时,了解了一些简 ...