Files
wagslane 9be3074de6 first
2023-05-01 15:25:27 -06:00

45 lines
2.0 KiB
Markdown

# Constraints
Sometimes you need the logic in 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:
```go
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 constraint 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*.
## Creating a custom constraint
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.
```go
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
}
```
## Assignment
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. First, it should check if the user has a balance with enough funds to be able to pay for the cost of the `newItem`. If they don't then return an "insufficient funds" error.
If they *do* have enough funds:
* Add the line item to the user's history by appending the `newItem` to the slice of `oldItems`. This new slice is your first return value.
* Calculate the user's new balance by subtracting the cost of the new item from their balance. This is your second return value.