

0 / 2 embers
0 / 3000 xp
click for more info
Complete a lesson to start your streak
click for more info
Difficulty: 6
click for more info
Not enough gems
Cost: 6 gems
1: Generics in Go
incomplete
2: Why Generics?
incomplete
3: Constraints
incomplete
4: Interface Type Lists
incomplete
5: Parametric Constraints
incomplete
6: Naming Generic Types
incomplete
Back
ctrl+,
Next
ctrl+.
This lesson's interactive features are locked, please to keep using them
Sometimes you need your generic function to know something about the types it operates on. The example we used in the first exercise didn't need to know anything about the types in the slice, so we used the built-in any constraint:
func splitAnySlice[T any](s []T) ([]T, []T) {
mid := len(s)/2
return s[:mid], s[mid:]
}
Constraints are just interfaces that allow us to write generics that only operate within the constraints of a given interface type. In the example above, the any constraint is the same as the empty interface because it means the type in question can be anything.
Let's take a look at the example of a concat function. It takes a slice of values and concatenates the values into a string. This should work with any type that can represent itself as a string, even if it's not a string under the hood. For example, a user struct can have a .String() that returns a string with the user's name and age.
type stringer interface {
String() string
}
func concat[T stringer](vals []T) string {
result := ""
for _, val := range vals {
// this is where the .String() method
// is used. That's why we need a more specific
// constraint instead of the any constraint
result += val.String()
}
return result
}
We have different kinds of "line items" that we charge our customer's credit cards for. Line items can be things like "subscriptions" or "one-time payments" for email usage.
Complete the chargeForLineItem function.