Go-Interface

要点

  • interface关键字用来定义一个接口
  • Go没有implements、extends等关键字
  • 实现一个接口的方法就是直接定义接口中的方法
  • 要实现多态,就要用指针或&object语法

示例

package main
import "fmt"
import "math"

type Shape interface {
    area() float64 
}

type Circle struct {
    r float64 
}

func (c *Circle) area() float64 {
    return math.Pi * c.r * c.r
}

type Rectangle struct {
    length, width float64 
}

func (r *Rectangle) area() float64 {
    return r.length * r.width;
}

func totalArea(shapes ... Shape) (total float64) {
    total = 0 
    for _, shape := range shapes {
        total += shape.area()
    }

    return 
}

func main() {
    circle := Circle{r:5}
    ractangle := Rectangle{3, 4}

    /*.\helloworld.go:40: cannot use circle (type Circle) as type Shape in argument to totalArea:
        Circle does not implement Shape (area method has pointer receiver)
    fmt.Println(totalArea(circle, ractangle)) // L40  */

    fmt.Println(totalArea(&circle, &ractangle))
}

再论传值与传引用

在上面的代码中,注意到totalArea()声明的类型是Shape,但在后面调用的时候传入的是&cirlce这种。因此,冒出来一个疑问:为什么一个是“对象”,一个是地址(指针),却能够运行呢?

曾经考虑过是否Go和Java一样,存在基本类型和对象(用户自定义等)传值、传引用的区别。。。为此,有下面一系列的验证。

基本类型

package main
import "fmt"

func foo(i int) {
    fmt.Println(i)
}

func main() {
    i := 5 
    foo(i)

    /* cannot use &i (type *int) as type int in argument to foo
    foo(&i)*/
}

结构体类型

package main
import "fmt"

type Data struct {
    x int
}

func (data* Data) debug() {
    fmt.Println(data.x)
}

func foo(data Data) {
    data.x++
}

func bar(data *Data) {
    data.x++
}

func main() {
    data := Data{1}
    data.debug()

    // cannot use &data (type *Data) as type Data in argument to foo
    //foo(&data)

    foo(data)
    data.debug()
}

特殊的interface

package main
import "fmt"

type Debugger interface {
    debug()
}

type Data struct {
    x int
}

func (data* Data) debug() {
    fmt.Println(data.x)
}

func foo(debugger Debugger) {
    debugger.debug()
}

func bar(debugger *Debugger) {
    //debugger.debug undefined (type *Debugger is pointer to interface, not interface)
    //debugger.debug()

    (*debugger).debug()

    //syntax error: unexpected >, expecting expression
    //debugger->debug()
}

func main() {
    data := Data{1}
    data.debug()

    /*cannot use data (type Data) as type Debugger in argument to foo:
      Data does not implement Debugger (debug method has pointer receiver)*/
    //foo(data)

    foo(&data)

    /*cannot use &data (type *Data) as type *Debugger in argument to bar:
        *Debugger is pointer to interface, not interface*/
    //bar(&data)

    /*cannot use data (type Data) as type *Debugger in argument to bar:
        *Debugger is pointer to interface, not interface*/
    //bar(data)
}

约定俗成(???)

假定接口为:

type I interface {...}

实现该接口的类为:

type Concreate struct {...}

仅依赖于接口的函数:

func foo(i I) {...}

调用约定:

concreate := Concreate {...}
foo(&concreate)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Redis 是一个开源的内存数据存储系统,提供了丰富的数据结构和功能,被广泛用于缓存、消息队列、实时统计等场景。为了与 Redis 进行交互,可以使用各种编程语言提供的 Redis 客户端库。 Redis 客户端库允许开发者通过编程语言来与 Redis 服务器进行通信,并执行各种操作,例如设置和获取键值对、执行批量操作、发布和订阅消息等。 不同的编程语言提供了不同的 Redis 客户端库,以下是一些常用的编程语言与对应的 Redis 客户端库: - Python: `redis-py` (https://github.com/andymccurdy/redis-py) - Java: Jedis (https://github.com/xetorthio/jedis) - Node.js: `ioredis` (https://github.com/luin/ioredis) - Ruby: `redis-rb` (https://github.com/redis/redis-rb) - Go: `go-redis` (https://github.com/go-redis/redis) 使用这些客户端库,您可以连接到 Redis 服务器,并执行各种操作。例如,在 Python 中使用 `redis-py` 客户端库连接到 Redis 服务器并设置一个键值对,可以执行以下代码: ```python import redis # 创建 Redis 客户端 r = redis.Redis(host='localhost', port=6379, db=0) # 设置键值对 r.set('key', 'value') # 获取键值对 value = r.get('key') print(value) ``` 上述代码创建了一个 Redis 客户端对象 `r`,连接到本地的 Redis 服务器(默认端口为 6379),并设置了一个键值对 `key: value`。然后,通过 `get` 方法获取键 `key` 的值,并打印出来。 根据您使用的编程语言和相应的 Redis 客户端库,您可以以类似的方式与 Redis 进行交互。请参考相应的文档和示例代码以了解更多细节和操作。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值