The Go programming language is still new and growing in popularity. I've been playing with it for a few months, learning by writing a blog engine. I've enjoyed it, and when I realized I had the basic blog features I needed, I tossed out my old PHP based blog and switched to using Go full time.
When I started to write this post I thought I would have a couple of little differences in golang vs php. As I wrote, I realized that they are very different. At their core they perform logic, and manipulate input to create output. But they take very different paths to get that output.
Go is simple and small. There are not a lot of keywords or functions to remember. Everything is tidy and thought out with specific intent before being included in Go. It feels easy to use. The syntax is similar to PHP so I felt at home. The build environment and online documentation made it easy for me to get working code up quickly.
PHP, on the other hand, is huge. There are years of organically grown functions. Many that do the same or similar things, with similar names to keep it confusing. PHP is easy to use because it's direct. It doesn't require a lot of knowledge or setup to quickly create something useful. But as your program grows it's complexity and maintainability grow with it.
Static vs dynamic types
The first difference you will notice deals with how variables are managed. Go is statically typed and PHP is dynamically typed. In PHP a variable can be of any kind. It could be a number (integer or floating point), string, boolean, object, or array. If you have a variable that was originally set to a number you can later assign text to it. If you have a variable that is a text zero you can pass it functions that are looking for an integer or boolean. PHP will do it's best to convert between types depending on what it needs.
Go is the opposite of this. Once a variable is declared as a specific type it can only ever contain data of that type.
When I wrote PHP I made a point to create single use variables that were effectively statically typed. I would cast variables when I knew a type cast was needed. I did this to keep my code simple and have greater control over type conversions. Because of this my transition to Go's statically typed variables was easy.
Objects and inheritance
Go does not have objects like PHP does. It has structs, basic data structures which act like PHP objects that do not have methods. But structs can have methods attached to them later. This may seem like an object oriented nature but it is rather different. To me it seems like Go does objects inside out. The language designer want you think about building programs through composition. You are encouraged to make small piece of code and pull them together to do large things.
Go uses implied interfaces for code reuse. Interface type declarations are a set of methods. As long as your type has at least those methods it fulfills that interface. And will work wherever that interface is used.
Program structure
There are many many ways to write PHP programs. The first of the two most popular is old school PHP mixed in with HTML. Each page is a stand alone program, or at the least includes a "base" or "functions.php" from a global location. The second is strict separation of PHP classes and functionality organized into a semi-standardized folder structure. This method uses an "autoloader" to find and load PHP code when it's needed by the request.
For my Go blog engine I used a structure closer to the second. I have a project directory with source, binary, static root (html, css, js), and Go templates. The Go source and dependencies live in the src and pkg directories. When compiled the binary lives in bin. The html, css and javascript that are separate from the program logic are stored in the web root. The only publicly accessible folder. My named templates live in the templates directory.
Hosting environment
PHP runs on commodity hosting environments amazingly well. It has a simple understanding of what a program is. A PHP file in the web root is requested, compiled and the output sent to the browser. Go is not as straight forward to setup. It designed for big software on servers that you control. This offers greater control at the expense of a hosting complexity.
There are many golang hosting solutions, I personally run my own server on a VPS. I use Apache for several sites and found a way to integrate my Go program into my existing setup. The Go binary listens on localhost, and apache forwards requests for nonexistent files or directories to the Go binary.
I'm not sure how easy it would be for a commodity host to setup a Go environment that is as simple to use as a PHP setup. Google does offer Go on it's AppEngine platform. My recommendation is to use a VPS and manage the servers yourself.
Compiled vs run-time
PHP, in it's simplest form, is dynamically compiled on each server request. The code lives in the web root and is compiled fresh each time a browser hits that page. Go on the other hand is compiled once into a static binary. The program is compiled one time, and pulls in all the program's dependencies, to create one single binary file. This executable file, in the case of a web app, is pointed to from your web server. Any request that need to be routed to the web app are sent to the binary, executed and the result returned to the browser.
This will affect your workflow. With PHP you can simply make small edits and test them in a browser with a simple refresh. Go has an extra build step, where you must compile and restart the binary before you refresh your browser. Go is very fast when it comes to compile times. So fast that by the time I switch to my browser and refresh the recompile and restart are complete. The speed of testing hasn't hindered me. Still, I find my workflow changing in subtle ways. Now I take more time to implement changes and updates to my blog engine before testing. Whereas with PHP I would test sooner on smaller edits.
Package management
Go has a built-in tool to get and install third party libraries. go get http://path.to.source.code
will download the source and put it in the pkg directory ready for use. Until recently with Composer PHP did not have a native package management tool. All PHP dependencies had to be manually copied into the right location for the program to use. Go's package management tool is direct and simple compared to Composer.
Go is very strict about how it uses packages of external libraries. PHP will include() any code it is told to. Or try to load any code sent to the autoloader(). PHP will let you litter your source with unused variables and functions. Go will not.
Go will complain very loudly by not compiling. At first you will be frustrated by this, but it will pass. My programming style adapted to this strictness. Which is not a whimsical desire of the Go team. It keeps your code clean. I know that if my code compiles then every last piece of it is used somewhere. There is no ambiguity if a function is old an unneeded.
Code format: go fmt vs random style
The great syntax formatting wars are coming to an end. Go includes a tool called go fmt
which you can use to automatically format your source files. In this Go is opinionated. It uses tabs not spaces for indentation.
The syntax style very strict as well. If statements don't use parentheses around the expression block, and you must use curly braces around the statement block. No single line if statements anymore.
Templating: Go's crystalline structures vs PHP's spaghetti
One of the most dramatic differences for me was in how Go implemented it's templating system for outputting HTML pages.
PHP uses the core PHP language as it's templating system. It inter-mingles HTML and PHP code. The HTML is sent as is to the browser, and the PHP is processed and the output sent to the browser. It is a wonderful system for working with small PHP scripts. It's simple and allows for the whole of the script to exist in a single page. But it breaks down when your program grows. It limits code reuse and creates confusing boundaries between code parts. It creates spaghetti code.
Go uses a simpler templating system. One that I am still getting used to. It uses an external templating syntax that is pulled into Go and processed. You create name template parts and pull them into each other to create full pages. You then load the top named template into Go and pass your data into it.
The Go template itself has little logic, as far as I can tell. You have the option to test for the existence of a named variable, but not what it is. So you can't compare if a value is equal to something, or is larger than some number. At least I have yet to find it.
For more complex needs you can create custom filters. These are functions that are run from the template on the data. So you can add them to specific parts of your template. I created a filter that checks for a tag in a blog post and stop rendering if it finds one. This allows for post excerpts on pages that have multiple posts; like the homepage.
Like the rest of Go the spartan nature of the templating language is purposeful. Instead of creating quick fixes here in this one template, you have to adjust the data sent to the template. You are forced to fix the issue in the most appropriate place, the business logic.
The End
These are a comparison of the most apparent differences between Go and PHP. Go has other features that are not available in PHP, such as channels and goroutines for concurrency. But their differences are deeper than the syntax and available libraries. Go has a philosophy of small and simple. It feels easy and direct. In it's strict nature it feels liberating.
PHP programmers who are used to fast and loose will feel frustrated and hobbled by Go's strictness. But if you are like me, and desire a simplicity of nature and directness of design, then you will enjoy working with Go.
有疑问加站长微信联系(非本文作者)