doq8211 2018-07-10 05:36
浏览 50
已采纳

防止仅字段结构在Go中重复功能

EDIT: I have updated the below code samples to better illustrate the problem.

Let's say I have 2 field-only structs that do not need any functionality.

Assume that they represent 2 types of similar data from a Database:

type Boy struct {
    Name          string
    FavoriteColor string
    BirthDay      time.Time
}

type Girl struct {
    Name           string
    FavoriteFlower string
    BirthDay       time.Time
}

I write a function for the Boy struct that prints a greeting based on the given date and the boy's information.

Assume that this is a placeholder for a much more complicated function that does something based on a time.Time field, and returns an int that will be used elsewhere in the application:

func CheckBirthDayBoy(date time.Time, boy Boy) int {
    numDays := 0

    if date.Before(boy.BirthDay) {
        // Greet how many days before birthday
        numDays = int(boy.BirthDay.Sub(date).Hours() / 24)
        fmt.Println("Hi, " + boy.Name + "! Only " + strconv.Itoa(numDays) + " days until your birthday! I hear your favorite color is " + boy.FavoriteColor + "!")
    } else if date.Equal(boy.BirthDay) {
        // Greet happy birthday
        fmt.Println("Happy birthday, " + boy.Name + "! I brought you something " + boy.FavoriteColor + " as a present!")
    } else {
        // Greet belated birthday
        numDays = int(date.Sub(boy.BirthDay).Hours() / 24)
        fmt.Println("Sorry I'm " + strconv.Itoa(numDays) + " days late, " + boy.Name + "! Here is something " + boy.FavoriteColor + " to cheer you up!")
    }

    return numDays
}

Now, since Go is a strongly-typed language, and does not have Generics, I end up having to write a duplicate function just for the Girl struct:

func CheckBirthDayGirl(date time.Time, girl Girl) int {
    numDays := 0

    if date.Before(girl.BirthDay) {
        // Greet how many days before birthday
        numDays = int(girl.BirthDay.Sub(date).Hours() / 24)
        fmt.Println("Hi, " + girl.Name + "! Only " + strconv.Itoa(numDays) + " days until your birthday! I hear your favorite flower is a " + girl.FavoriteFlower + "!")
    } else if date.Equal(girl.BirthDay) {
        // Greet happy birthday
        fmt.Println("Happy birthday, " + girl.Name + "! I brought you a " + girl.FavoriteFlower + " as a present!")
    } else {
        // Greet belated birthday
        numDays = int(date.Sub(girl.BirthDay).Hours() / 24)
        fmt.Println("Sorry I'm " + strconv.Itoa(numDays) + " days late, " + girl.Name + "! Here is a " + girl.FavoriteFlower + " to cheer you up!")
    }

    return numDays
}

Is there a way to avoid code duplication for simple structs like the ones above? I do not want to duplicate my function for each new struct that I want to implement it for.

Interfaces are not an option here because both structs do not have any Functionality to speak of (and adding dummy functionality for the sake of satisfying an Interface sounds like a backwards solution to me).

EDIT: After considering the solution I accepted, I now believe that Interfaces are also a valid solution to this problem. Thanks to @ThunderCat for bringing it up!

  • 写回答

2条回答 默认 最新

  • doy2255 2018-07-10 06:22
    关注

    As ThunderCat mentions in the comments: pull common code into a separate function and call.

    func CheckBirthday(date, birthdate time.Time, name, gift string) (numDays int) {
        if date.Before(birthdate) {
            // Greet how many days before birthday
            numDays = int(birthdate.Sub(date).Hours() / 24)
            fmt.Printf("Hi, %s! Only %d days until your birthday! I hear your favorite is %s!
    ", name, numDays, gift)
        } else if date.Equal(birthdate) {
            // Greet happy birthday
            fmt.Printf("Happy birthday, %s! I brought you a %s as a present!
    ", name, gift)
        } else {
            // Greet belated birthday
            numDays = int(date.Sub(girl.birthday).Hours() / 24)
            fmt.Printf("Sorry I'm %d days late, %s! Here is a %s to cheer you up!
    ", numDays, name, gift)
        }
    
        return
    }
    
    func CheckBirthdayBoy(date time.Time, boy Boy) int {
        return CheckBirthday(date, boy.BirthDay, boy.Name, boy.FavoriteColor)
    }
    
    func CheckBirthdayGirl(date time.Time, girl Girl) int {
        return CheckBirthday(date, girl.BirthDay, girl.Name, girl.FavoriteFlower)
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统
  • ¥15 真我手机蓝牙传输进度消息被关闭了,怎么打开?(关键词-消息通知)
  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度