Why is port a string and not an integer?

This is because what appears after the colon can be either a port number or service name.

The following is a valid example where the service name is used instead of a port number:

listener, err := net.Listen("tcp", "localhost:https") // port 443
// ...

The port mapping for a particular service can be looked up using net.LookupPort. On Unix systems, the /etc/services file is sourced for the mappings.