如何调用实现接口的结构的特定方法

问题描述

我有以下接口和一些实现它的结构:

package main

import "fmt"

type vehicle interface {
    vehicleType() string
    numberOfWheels() int
    EngineType() string
}

// -------------------------------------------

type truck struct {
    loadCapacity int
}

func (t truck) vehicleType() string {
    return "Truck"
}

func (t truck) numberOfWheels() int {
    return 6
}

func (t truck) EngineType() string {
    return "Gasoline"
}

// -------------------------------------------
type ev struct {
    capacityInKWh int
}

func (e ev) vehicleType() string {
    return "Electric Vehicle"
}

func (e ev) numberOfWheels() int {
    return 4
}

func (e ev) EngineType() string {
    return "Electric"
}

func (e ev) Capacity() int {
    return e.capacityInKWh
}

// -------------------------------------------

type dealer struct{}

func (d dealer) sell(automobile vehicle) {
    fmt.Println("Selling a vehicle with the following properties")
    fmt.Printf("Vehicle Type: %s \n",automobile.vehicleType())
    fmt.Printf("Vehicle Number of wheels: %d \n",automobile.numberOfWheels())
    fmt.Printf("Vehicle Engine Type: %s \n",automobile.EngineType())

    if automobile.EngineType() == "Electric" {
        fmt.Printf("The battery capacity of the vehicle is %d KWh",automobile.Capacity())
        //fmt.Printf("Here")
    }
}

func main() {

    volvoTruck := truck{
        loadCapacity: 10,}

    tesla := ev{
        capacityInKWh: 100,}

    myDealer := dealer{}
    myDealer.sell(volvoTruck)
    fmt.Println("---------------------------")
    myDealer.sell(tesla)

}
我的Sell结构中的

dealer{}方法收到一个接口。在此方法中,我想调用一个仅存在于实现接口的结构之一上的方法,而不存在于其他方法中:

if automobile.EngineType() == "Electric" {
            fmt.Printf("The battery capacity of the vehicle is %d KWh",automobile.Capacity())
        }

请注意,Capacity()仅存在于ev{}中,而不存在于truck{}中。有没有一种方法可以不必将此方法添加到强制所有实现都使用它的接口中?

解决方法

您可以使用type assertion检查方法是否存在。检查值(或更具体地说,它的类型)是否具有所需的方法,如果有,可以调用它。

可以通过检查值是否使用单个方法实现接口来实现对方法的检查:

if hc,ok := automobile.(interface {
    Capacity() int
}); ok {
    fmt.Printf("The battery capacity of the vehicle is %d KWh",hc.Capacity())
}

然后将输出(在Go Playground上尝试):

Selling a vehicle with the following properties
Vehicle Type: Truck 
Vehicle Number of wheels: 6 
Vehicle Engine Type: Gasoline 
---------------------------
Selling a vehicle with the following properties
Vehicle Type: Electric Vehicle 
Vehicle Number of wheels: 4 
Vehicle Engine Type: Electric 
The battery capacity of the vehicle is 100 KWh

如果为它创建一个命名接口类型会更好:

type HasCapacity interface {
    Capacity() int
}

然后:

if hc,ok := automobile.(HasCapacity); ok {
    fmt.Printf("The battery capacity of the vehicle is %d KWh",hc.Capacity())
}

输出将相同,请在Go Playground上尝试一下。

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...