In go , interfaces are satisfied by any type that implements all of the methods defined in the interface. This makes Go interfaces “open” types, meaning that any type can satisfy an interface at any time. However, did you know that Go actually has a mechanism for restricting who can implement these types? This go-tip will tell you how you can accomplish this.
It’s been a long time since I’ve last updated this blog – and I think I’m finally ready to reboot it. A lot has changed since my last article nearly 3 years ago: I changed jobs a number of times, and am now begrudgingly working as a Go developer professionally. I found new love of the Rust programming language and started writing rust projects in my spare time. I’ve…
A little while back a friend of mine and I were talking about serialization of struct objects as raw bytes. He was working with generated objects that contain padding, but the objects needed to be serialized without the padding; for example: struct Foo { char data0 ; // 3 bytes padding here int data1 ; }; In the case he described, there are dozens of object types that need to be serialized, and…
Getting the name of a type in C++ is a hassle. For something that should be trivially known by the compiler at compile-time, the closest thing we have to getting the type in a cross-platform way is to use std::type_info::name which is neither at compile-time, nor is it guaranteed to be human-readable. In fact, both GCC and Clang actually return the compiler’s mangled name rather than the…
The Builder pattern is a common design in software development for late-binding inputs to allow for iterative construction. This pattern, when applied in c++ , leaves one very obvious question: Can we present this to consumers in an optimal way? More specifically: when we call build() , should we be moving any temporary internal state, or copy it? Can we express both in a safe and idiomatic way to…
Note The C++WTF segment shines a light on the dark and esoteric corners of the C++ language for fun and profit The C++ standards committee is very strongly against producing any kind of breaking changes when considering new language features – especially keywords. Over the course of standardization, this has lead to terms like auto being repurposed, or awkward keywords like co_await and…
Note This is part 3 of a 3 part series. In the previous post we updated our Delegate object that we’ve been working on since the first post to support covariance. In this post, we will look at how to make this a true zero-overhead utility
Note This is part 2 of a 3 part series. In the previous post , we saw how we could build a simple and light-weight Delegate type that binds free functions, and member functions. However we have a notable limitation that we require specifying the type of the members being bound (e.g. d.bind<Foo,&Foo::do_something>() ). Additionally, we’re forced to bind only the exact type. We can’t…
Note This is part 1 of a 3 part series. When working in C++ systems, a frequent design pattern that presents itself is the need to bind and reuse functions in a type-erased way. Whether it’s returning a callback from a function, or enabling support for binding listeners to an event (such as through a signal or observer pattern), this is a pattern that can be found everywhere.