If "Foo" represents anything at all complex or stateful (e.g. a database connection, a model of some data, an HTTP server, etc.), and you might want to extend it later, it's going to be messy.
If you assume there is only ever going to be one implementation of "Foo", then there's nothing to be gained by using an interface over a struct with private fields. If there are other implementations, then you have to update every implementation in sync with the interface every time you add or change a method. That might be very difficult or even nigh impossible if they're in different packages maintained by different people.
My point is to be very careful with how you use interfaces. They're designed to represent abstractions that apply to multiple data types. Looking at the standard library, Reader, Writer, Stringer, http.Handler etc are all pretty useful as interfaces. database/sql/driver has the Driver interface, which is about as complicated as you should allow an interface to become. Notice that nothing in database/sql implements the Driver interface -- it's strictly for polymorphism, to consume external implementations -- and nearly every type in database/sql is a raw struct.
If you assume there is only ever going to be one implementation of "Foo", then there's nothing to be gained by using an interface over a struct with private fields. If there are other implementations, then you have to update every implementation in sync with the interface every time you add or change a method. That might be very difficult or even nigh impossible if they're in different packages maintained by different people.
My point is to be very careful with how you use interfaces. They're designed to represent abstractions that apply to multiple data types. Looking at the standard library, Reader, Writer, Stringer, http.Handler etc are all pretty useful as interfaces. database/sql/driver has the Driver interface, which is about as complicated as you should allow an interface to become. Notice that nothing in database/sql implements the Driver interface -- it's strictly for polymorphism, to consume external implementations -- and nearly every type in database/sql is a raw struct.