golang中接口interface和struct结构类的分析

再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 1111111
the value is 444444
the value is 1111111
the value is 33333
the value is 222222222
the type is Stryc interface, the function value is  1111111
the type is myCls, the function value is  222222222 the struct value is  222222222
the type is myCls, the function value is  1111111 the struct value is  1111111
the type is Stryc interface, the function value is  222222222

原文地址:https://www.cnblogs.com/zhangdewang/p/10612089.html

时间: 2024-10-10 10:04:01

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

Android中接口(Interface)的简单使用

  Android中接口(Interface)的简单使用 Java中的接口可以被看作是只包含常量和抽象方法的抽象类 . 可以使用如下方式定义一个接口: public interface InterfaceDemo { int i = 10; void method1(); int method2(); } 使用1: 解决“多重继承”的问题 Java语言本身是不支持类的多重继承(多重继承是指一个类从多个类继承而来,即一个类拥有多个超类)的,但一个类却可以实现多个接口.这样,我们可以将一些抽象方法定

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

3.接口持有多个类的共享常量 (视频下载) (全部书籍) 接口另一主要功能,马克-to-win: 可以使用接口来引入多个类的共享常量.所有的这些变量名都将作为常量看待.所有定义在接口中的常量都默认为public.static和final.原因见后面. 下面的例子当中,如果Server回答的结果是0或1,程序可读性太差,效果绝对没有YES或NO好.所以就把YES和NO放到了Client和Server的共同的接口ConstantbaseM_to_win当中. note: the following

golang中的interface{}转其他类型

golang中的string是可以转换为byte数组或者rune数组 但是其实byte对应的类型是uint8,而rune对应的数据类型就是int32 所以string可以转换为四种类型 //interface转其他类型————返回值是interface,直接赋值是无法转化的        //interface 转string        var a interface{}        var str5 string        a = "3432423"        str5

Java中Collection、Map常用实现类研究分析

接口/实现类 描述 key是否可为null 为null是否报错 key是否重复 key重复是否报错 key是否和添加一致 是否线程安全 List 一组元素的集合 ArrayList 基于数组存储,读取快 是 否 是 否 是 否 LinkedList 基于双向链表存储,插入快 是 否 是 否 是 否 Vector 基于数组存储,效率较ArrayList慢 是 否 是 否 是 是 Map HashMap 是 否 否 否 否 否 TreeMap 基于红黑树实现 否 是 否 否 否 否 Concurre

golang中interface接口的深度解析

什么是interface,简单的说,interface是一组method的组合,下面这篇文章主要给大家深度解析了关于golang中的interface接口,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧. 一 接口介绍 如果说gorountine和channel是支撑起Go语言的并发模型的基石,让Go语言在如今集群化与多核化的时代成为一道亮丽的风景,那么接口是Go语言整个类型系列的基石,让Go语言在基础编程哲学的探索上达到前所

[golang note] 接口使用

侵入式接口 √ 在其他一些编程语言中,接口主要是作为不同组件之间的契约存在,即规定双方交互的规约. √ 对契约的实现是强制的,即必须确保用户的确实现了该接口,而实现一个接口,需要从该接口继承. √ 如果一个类实现了接口A,即便另一个接口B与A的方法列表相同,甚至连接口名都相同,但位于不同的命名空间下,那么编译器并不认为这两个接口是一样的. √ 所谓侵入的主要表现在于实现继承接口的类需要明确声明自己实现自某个接口. √ 侵入式接口常纠结的问题是:应该提供哪些接口好呢?如果两个类实现了相同的接口,应

浅析C#中接口的重要性

C#中有了接口这一概念.我觉得接口就像是C++中的抽象基类. 接口可以理解为是一种约定,使得实现这个接口的类或是结构在形式上保持一致. 声明接口: 语法和声明抽象类完全相同.  public interface IBankAccount { void PayIn(decimal amount); bool Withdraw(decimal amount); decimal Balance { get; } } 注意:接口中只能包含方法.属性.索引器和事件的声明.不允许声明成员上的修饰符,即使是p

Java简明教程 09. 抽象类(abstract class)和接口(interface)

抽象类(abstract class) 描述抽象的事物,  比如人类(human), 就是一个抽象类. 对于人类这个抽象类, 具体的就是某一个人, 比如张三(男)啊, 小红(女)啊,虽然说人都会eat, 可是男人和女人的eat似乎又是不一样的.男人一般都是大口大口的吃, 而女人比较慢条斯理. AbstractDemo.java 1 abstract class Human { //抽象类, 特点: 1. 前面有abstract修饰 2 // 2. 无法直接生成一个对象,需要子类去继承这个类, 并

C#中接口应用注意事项

使用C#接口应注意几个问题: 1.C#中的接口是独立于类来定义的.这与 C++模型是对立的,在 C++中接口实际上就是抽象基类. 2.接口和类都可以继承多个接口. 3.类可以继承一个基类,接口根本不能继承类.这种模型避免了 C++的多继承问题,C++中不同基类中的实现可能出现冲突.因此也不再需要诸如虚拟继承和显式作用域这类复杂机制.C#的简化接口模型有助于加快应用程序的开发. 4.一个接口定义一个只有抽象成员的引用类型.C#中一个接口实际所做的,仅仅只存在着方法标志,但根本就没有执行代码.这就暗