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条)

报告相同问题?

悬赏问题

  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题
  • ¥15 请完成下列相关问题!
  • ¥15 drone 推送镜像时候 purge: true 推送完毕后没有删除对应的镜像,手动拷贝到服务器执行结果正确在样才能让指令自动执行成功删除对应镜像,如何解决?