if err != nil { return err; }
is an antipattern. Not because it's verbose, but because you are supposed to handle the error, not pass it right through, in most cases. 10010000 = A
01100110 = B
00001001 = M1 = ~A & ~B
00101010 = M2 = M1 + (A << 1) + 1
00100010 = M3 = M2 & ~M1
Note that this code treats newlines as non-spaces, meaning if a line comprises only spaces, the terminating NL character is returned. You can have it treat newlines as spaces (meaning a line of all spaces is not a match) by computing M4 = M3 & ~A.
That said, the key insight of the exception craze is that error returns are a normal part of a functions behaviour and as such should not use extraordinary control flow to take place.
Exceptions (panics) are used for things that should never happen or are indicative of a programmer error, like nil dereferences or out-of-bounds array accesses. That is, things where the programmer is not expected to provide reasonable behaviour on the API level if it happens (but perhaps there is a whole-program fault handler to shut down cleanly).
Opening a file that does not exist? Database record not found? Invalid credentials? These should be anticipated by the programmer and can occur at any time. Not exceptions, normal return values. Go requests that you think about these possibilities instead of pretending they can be ignored.