防止仅字段结构在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!

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

Would type switch work for you?

func CheckBirthDay(date time.Time, i interface{}) int {
    switch v := i.(type) {
    case Boy:
      CheckBirthDay(date, v.Birthday)
    case Girl:
      CheckBirthDay(date, v.Birthday)
    default:
      DoSomething()
    }
}

func CheckBirthDay(date time.Time, bday time.Time) int {
    ...
}