编辑:我更新了以下代码示例,以更好地说明问题。
比方说,我有2个仅用于字段的结构,不需要任何功能。
假设它们代表数据库中两种相似的数据:
type Boy struct {
Name string
FavoriteColor string
BirthDay time.Time
}
type Girl struct {
Name string
FavoriteFlower string
BirthDay time.Time
}
我为Boy
结构编写了一个函数,该函数根据给定的日期和男孩的信息打印问候语。
假定这是一个更为复杂的函数的占位符,该函数基于time.Time
字段执行某操作,并返回一个int
并将在应用程序的其他地方使用:
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
}
现在,由于Go是一种强类型语言,并且没有泛型,所以我最终不得不为Girl
结构编写一个重复函数:
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
}
有没有一种方法可以避免像上面那样的简单结构的代码重复?我不想为要为其实现的每个新结构复制函数。
接口在这里不是一个选择,因为两个结构都没有任何功能可言(并且为满足接口而添加虚拟功能听起来像是我的倒退解决方案)。 >
编辑:在考虑了我接受的解决方案之后,我现在认为接口也是针对此问题的有效解决方案。感谢@ThunderCat带来了它!
答案 0 :(得分:5)
正如ThunderCat在评论中提到的:将通用代码放入单独的函数中并调用。
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!\n", name, numDays, gift)
} else if date.Equal(birthdate) {
// Greet happy birthday
fmt.Printf("Happy birthday, %s! I brought you a %s as a present!\n", 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!\n", 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 :(得分:0)
类型开关对您有用吗?
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 {
...
}