When you come from C++ world, you already knew std::enable_if
concept. To have the same logic in Go, we need to do some development as there is no straight way to handle it.
What exactly it does in C++?
std::enable_if
is a standard library to enable methods or functions based on predefined conditions.
Official definition is:
|
|
If B is true
, std::enable_if
has a public member typedef type, equal to T; otherwise, there is no member typedef.
Let’s see a sample code to grasp the concept.
Imagin you have 3 types of data structure: Car
, Bike
, and Walk
, and you want to have a method like Repair
, “if” types are Car
and Bike
.
Is it the place where std::enable_if
comes:
|
|
When we try to compile it, it will raise an error because there is no “Reapir” function defined for Walk
type:
$ g++ code.cpp
code.cpp: In function ‘int main()’:
code.cpp:46:11: error: no matching function for call to ‘Repair(Walk&)’
46 | Repair(data_walk);
| ~~~~~~^~~~~~~~~~~
code.cpp:34:52: note: candidate: ‘template<class T> typename std::enable_if<IsVehicle<T>::value>::type Repair(T)’
34 | typename std::enable_if<IsVehicle<T>::value>::type Repair(T data_type) {
| ^~~~~~
code.cpp:34:52: note: template argument deduction/substitution failed:
code.cpp: In substitution of ‘template<class T> typename std::enable_if<IsVehicle<T>::value>::type Repair(T) [with T = Walk]’:
code.cpp:46:11: required from here
code.cpp:34:52: error: no type named ‘type’ in ‘struct std::enable_if<false, void>’
The error is clear what happened exactly. This is very important to know that it happpend at compile time!
Now, as you got the general idea, we want to implement the same in Go!
Go implementation
In Go, there is no direct way exist to handle it. But, we can make our own one. It is important to know that std::enable_if
in C++ is useful for different scenarios and supports
different parameters and flexibility, but in Go we can’t handle all the scenarios and parameters and we should only implement based on requirements.
So, it this scenario, we only want to enable a function only for vehicles, the same as C++ implementation.
|
|
Now, let’s execute the code to see the result:
$ go run ./code.go
Repairing has started... {c1}
Repairing has started... {b1}
panic: error: no matching function for call to ‘Repair(Walk)’
goroutine 1 [running]:
main.EnableIf.func1({0x490640, 0xc000014280})
/home/mort/code.go:30 +0x225
main.main()
/home/mort/code.go:50 +0xd9
exit status 2
As source code and result demonstrate, it’s a runtime validation, while in C++ it’s compile-time validation.
The important thing for us was the general idea of how to implement enable_if
in Go.
It was the whole idea to talk about what is enable_if concept and how to achieve it in Go. I know it’s not a clean way to implement an idea in Go, but let’s consider it just as an idea.