2013-09-09 08:52:47 +04:00
-- -
2013-08-13 21:52:13 +04:00
name : Go
category : language
language : Go
filename : learngo . go
contributors :
- [ "Sonia Keys" , "https://github.com/soniakeys" ]
2014-01-25 01:30:11 +04:00
- [ "Christopher Bess" , "https://github.com/cbess" ]
2014-01-31 03:47:55 +04:00
- [ "Jesse Johnson" , "https://github.com/holocronweaver" ]
2014-02-03 00:11:15 +04:00
- [ "Quint Guvernator" , "https://github.com/qguv" ]
2014-05-12 00:33:08 +04:00
- [ "Jose Donizetti" , "https://github.com/josedonizetti" ]
2014-07-16 02:28:50 +04:00
- [ "Alexej Friesen" , "https://github.com/heyalexej" ]
2015-10-07 06:56:55 +03:00
- [ "Clayton Walker" , "https://github.com/cwalk" ]
2016-10-31 20:08:32 +03:00
- [ "Leonid Shevtsov" , "https://github.com/leonid-shevtsov" ]
2020-01-31 02:29:06 +03:00
- [ "Michael Graf" , "https://github.com/maerf0x0" ]
2020-02-27 14:50:39 +03:00
- [ "John Arundel" , "https://github.com/bitfield" ]
2013-08-13 21:52:13 +04:00
-- -
2014-09-05 17:05:13 +04:00
Go was created out of the need to get work done . It ' s not the latest trend
2018-07-06 18:41:46 +03:00
in programming language theory , but it is a way to solve real - world
2013-08-13 21:52:13 +04:00
problems .
2018-07-06 18:41:46 +03:00
It draws concepts from imperative languages with static typing .
2013-08-13 21:52:13 +04:00
It ' s fast to compile and fast to execute , it adds easy - to - understand
2018-07-06 18:41:46 +03:00
concurrency because multi - core CPUs are now common , and it ' s used successfully
in large codebases ( ~ 100 million loc at Google , Inc . ) .
2013-08-13 21:52:13 +04:00
2018-07-06 18:41:46 +03:00
Go comes with a good standard library and a sizeable community .
2013-08-13 21:52:13 +04:00
2013-08-14 06:59:19 +04:00
` ` ` go
2013-08-13 21:52:13 +04:00
// Single line comment
/ * Multi -
2014-09-05 17:05:13 +04:00
line comment * /
2013-08-13 21:52:13 +04:00
2019-10-23 01:11:23 +03:00
/ * A build tag is a line comment starting with // +build
2020-12-03 23:16:43 +03:00
and can be executed by go build - tags = "foo bar" command .
2019-10-23 01:11:23 +03:00
Build tags are placed before the package clause near or at the top of the file
followed by a blank line or other line comments . * /
// +build prod, dev, test
2013-08-13 21:52:13 +04:00
// A package clause starts every source file.
2023-01-11 10:10:03 +03:00
// main is a special name declaring an executable rather than a library.
2013-08-13 21:52:13 +04:00
package main
2013-08-14 01:12:54 +04:00
// Import declaration declares library packages referenced in this file.
2013-08-13 21:52:13 +04:00
import (
2014-07-16 02:28:50 +04:00
"fmt" // A package in the Go standard library.
"io/ioutil" // Implements some I/O utility functions.
2023-08-25 07:13:00 +03:00
m "math" // Math library with local alias m.
2014-07-16 02:28:50 +04:00
"net/http" // Yes, a web server!
2016-10-31 20:08:32 +03:00
"os" // OS functions like working with the file system
2014-07-16 02:28:50 +04:00
"strconv" // String conversions.
2013-08-13 21:52:13 +04:00
)
2014-09-05 17:05:13 +04:00
// A function definition. Main is special. It is the entry point for the
// executable program. Love it or hate it, Go uses brace brackets.
2013-08-13 21:52:13 +04:00
func main ( ) {
2014-07-16 02:28:50 +04:00
// Println outputs a line to stdout.
2018-07-06 18:41:46 +03:00
// It comes from the package fmt.
2014-07-16 02:28:50 +04:00
fmt . Println ( "Hello world!" )
2013-08-13 21:52:13 +04:00
2014-07-16 02:28:50 +04:00
// Call another function within this package.
beyondHello ( )
2013-08-13 21:52:13 +04:00
}
2013-08-14 01:12:54 +04:00
// Functions have parameters in parentheses.
2013-09-04 11:37:26 +04:00
// If there are no parameters, empty parentheses are still required.
2013-08-13 21:52:13 +04:00
func beyondHello ( ) {
2014-07-16 02:28:50 +04:00
var x int // Variable declaration. Variables must be declared before use.
x = 3 // Variable assignment.
// "Short" declarations use := to infer the type, declare, and assign.
y := 4
sum , prod := learnMultiple ( x , y ) // Function returns two values.
fmt . Println ( "sum:" , sum , "prod:" , prod ) // Simple output.
learnTypes ( ) // < y minutes, learn more!
2013-08-13 21:52:13 +04:00
}
2015-04-22 16:54:16 +03:00
/ * <- multiline comment
Functions can have parameters and ( multiple ! ) return values .
Here ` x ` , ` y ` are the arguments and ` sum ` , ` prod ` is the signature ( what ' s returned ) .
Note that ` x ` and ` sum ` receive the type ` int ` .
* /
2013-08-13 21:52:13 +04:00
func learnMultiple ( x , y int ) ( sum , prod int ) {
2014-07-16 02:28:50 +04:00
return x + y , x * y // Return two values.
2013-08-13 21:52:13 +04:00
}
// Some built-in types and literals.
func learnTypes ( ) {
2014-07-16 02:28:50 +04:00
// Short declaration usually gives you what you want.
2014-09-22 16:11:49 +04:00
str := "Learn Go!" // string type.
2013-08-13 21:52:13 +04:00
2014-07-16 02:28:50 +04:00
s2 := ` A "raw" string literal
2014-01-31 03:47:55 +04:00
can include line breaks . ` // Same string type.
2013-08-13 21:52:13 +04:00
2014-09-05 17:05:13 +04:00
// Non-ASCII literal. Go source is UTF-8.
2014-08-19 15:06:02 +04:00
g := 'Σ' // rune type, an alias for int32, holds a unicode code point.
2013-08-13 21:52:13 +04:00
2024-02-12 14:58:50 +03:00
f := 3.14159 // float64, an IEEE-754 64-bit floating point number.
2014-07-16 02:28:50 +04:00
c := 3 + 4i // complex128, represented internally with two float64's.
2013-08-13 21:52:13 +04:00
2015-04-22 16:54:16 +03:00
// var syntax with initializers.
2014-07-16 02:28:50 +04:00
var u uint = 7 // Unsigned, but implementation dependent size as with int.
var pi float32 = 22. / 7
2013-08-13 21:52:13 +04:00
2014-07-16 02:28:50 +04:00
// Conversion syntax with a short declaration.
n := byte ( '\n' ) // byte is an alias for uint8.
2013-08-13 21:52:13 +04:00
2014-07-16 02:28:50 +04:00
// Arrays have size fixed at compile time.
var a4 [ 4 ] int // An array of 4 ints, initialized to all 0.
2017-08-04 16:40:52 +03:00
a5 := [ ... ] int { 3 , 1 , 5 , 10 , 100 } // An array initialized with a fixed size of five
2017-07-04 14:34:50 +03:00
// elements, with values 3, 1, 5, 10, and 100.
2013-08-13 21:52:13 +04:00
2020-02-09 01:11:33 +03:00
// Arrays have value semantics.
a4_cpy := a4 // a4_cpy is a copy of a4, two separate instances.
a4_cpy [ 0 ] = 25 // Only a4_cpy is changed, a4 stays the same.
fmt . Println ( a4_cpy [ 0 ] == a4 [ 0 ] ) // false
2014-09-05 17:05:13 +04:00
// Slices have dynamic size. Arrays and slices each have advantages
2014-07-16 02:28:50 +04:00
// but use cases for slices are much more common.
2017-07-04 14:34:50 +03:00
s3 := [ ] int { 4 , 5 , 9 } // Compare to a5. No ellipsis here.
2014-07-16 02:28:50 +04:00
s4 := make ( [ ] int , 4 ) // Allocates slice of 4 ints, initialized to all 0.
var d2 [ ] [ ] float64 // Declaration only, nothing allocated here.
bs := [ ] byte ( "a slice" ) // Type conversion syntax.
2013-08-13 21:52:13 +04:00
2020-02-09 01:11:33 +03:00
// Slices (as well as maps and channels) have reference semantics.
s3_cpy := s3 // Both variables point to the same instance.
s3_cpy [ 0 ] = 0 // Which means both are updated.
fmt . Println ( s3_cpy [ 0 ] == s3 [ 0 ] ) // true
2014-08-11 07:02:31 +04:00
// Because they are dynamic, slices can be appended to on-demand.
2015-10-24 15:56:20 +03:00
// To append elements to a slice, the built-in append() function is used.
2014-08-11 07:02:31 +04:00
// First argument is a slice to which we are appending. Commonly,
2024-02-26 00:46:12 +03:00
// the slice variable is updated in place, as in example below.
2014-08-11 07:02:31 +04:00
s := [ ] int { 1 , 2 , 3 } // Result is a slice of length 3.
s = append ( s , 4 , 5 , 6 ) // Added 3 elements. Slice now has length of 6.
2014-08-11 07:04:49 +04:00
fmt . Println ( s ) // Updated slice is now [1 2 3 4 5 6]
2015-10-24 15:56:20 +03:00
2014-08-11 07:04:49 +04:00
// To append another slice, instead of list of atomic elements we can
2014-08-11 07:02:31 +04:00
// pass a reference to a slice or a slice literal like this, with a
2015-10-07 06:56:55 +03:00
// trailing ellipsis, meaning take a slice and unpack its elements,
2014-08-20 07:43:18 +04:00
// appending them to slice s.
s = append ( s , [ ] int { 7 , 8 , 9 } ... ) // Second argument is a slice literal.
2014-08-11 07:04:49 +04:00
fmt . Println ( s ) // Updated slice is now [1 2 3 4 5 6 7 8 9]
2014-08-11 07:02:31 +04:00
2014-07-16 02:28:50 +04:00
p , q := learnMemory ( ) // Declares p, q to be type pointer to int.
2014-09-05 17:05:13 +04:00
fmt . Println ( * p , * q ) // * follows a pointer. This prints two ints.
2013-08-13 21:52:13 +04:00
2014-07-16 02:28:50 +04:00
// Maps are a dynamically growable associative array type, like the
// hash or dictionary types of some other languages.
m := map [ string ] int { "three" : 3 , "four" : 4 }
m [ "one" ] = 1
2013-08-13 21:52:13 +04:00
2014-07-16 02:28:50 +04:00
// Unused variables are an error in Go.
2015-10-07 06:56:55 +03:00
// The underscore lets you "use" a variable but discard its value.
2017-07-04 14:34:50 +03:00
_ , _ , _ , _ , _ , _ , _ , _ , _ , _ = str , s2 , g , f , u , pi , n , a5 , s4 , bs
2016-10-31 20:08:32 +03:00
// Usually you use it to ignore one of the return values of a function
// For example, in a quick and dirty script you might ignore the
// error value returned from os.Create, and expect that the file
// will always be created.
file , _ := os . Create ( "output.txt" )
fmt . Fprint ( file , "This is how you write to a file, by the way" )
file . Close ( )
2014-07-16 02:28:50 +04:00
// Output of course counts as using a variable.
fmt . Println ( s , c , a4 , s3 , d2 , m )
2013-08-13 21:52:13 +04:00
2014-07-16 02:28:50 +04:00
learnFlowControl ( ) // Back in the flow.
2013-08-13 21:52:13 +04:00
}
2014-06-29 19:12:58 +04:00
// It is possible, unlike in many other languages for functions in go
2014-06-22 17:20:12 +04:00
// to have named return values.
2014-06-23 18:31:39 +04:00
// Assigning a name to the type being returned in the function declaration line
2014-06-29 19:12:58 +04:00
// allows us to easily return from multiple points in a function as well as to
2014-06-23 18:31:39 +04:00
// only use the return keyword, without anything further.
2014-06-22 17:20:12 +04:00
func learnNamedReturns ( x , y int ) ( z int ) {
2014-07-16 02:28:50 +04:00
z = x * y
return // z is implicit here, because we named it earlier.
2014-06-22 17:20:12 +04:00
}
2014-09-05 17:05:13 +04:00
// Go is fully garbage collected. It has pointers but no pointer arithmetic.
2013-08-13 21:52:13 +04:00
// You can make a mistake with a nil pointer, but not by incrementing a pointer.
2021-12-10 01:43:57 +03:00
// Unlike in C/Cpp taking and returning an address of a local variable is also safe.
2013-08-13 21:52:13 +04:00
func learnMemory ( ) ( p , q * int ) {
2014-07-16 02:28:50 +04:00
// Named return values p and q have type pointer to int.
p = new ( int ) // Built-in function new allocates memory.
2020-02-09 00:57:43 +03:00
// The allocated int slice is initialized to 0, p is no longer nil.
2014-07-16 02:28:50 +04:00
s := make ( [ ] int , 20 ) // Allocate 20 ints as a single block of memory.
s [ 3 ] = 7 // Assign one of them.
r := - 2 // Declare another local variable.
return & s [ 3 ] , & r // & takes the address of an object.
2013-08-13 21:52:13 +04:00
}
2021-11-27 23:21:17 +03:00
// Use the aliased math library (see imports, above)
2014-01-31 03:47:55 +04:00
func expensiveComputation ( ) float64 {
2014-07-16 02:28:50 +04:00
return m . Exp ( 10 )
2013-08-13 21:52:13 +04:00
}
func learnFlowControl ( ) {
2015-10-07 06:56:55 +03:00
// If statements require brace brackets, and do not require parentheses.
2014-07-16 02:28:50 +04:00
if true {
fmt . Println ( "told ya" )
}
2018-02-15 06:57:27 +03:00
// Formatting is standardized by the command line command "go fmt".
2014-07-16 02:28:50 +04:00
if false {
// Pout.
} else {
// Gloat.
}
// Use switch in preference to chained if statements.
x := 42.0
switch x {
case 0 :
2020-01-31 02:29:06 +03:00
case 1 , 2 : // Can have multiple matches on one case
2014-07-16 02:28:50 +04:00
case 42 :
// Cases don't "fall through".
2015-04-22 17:02:33 +03:00
/ *
There is a ` fallthrough ` keyword however , see :
https : //github.com/golang/go/wiki/Switch#fall-through
* /
2014-07-16 02:28:50 +04:00
case 43 :
// Unreached.
2015-04-21 09:26:38 +03:00
default :
// Default case is optional.
2014-07-16 02:28:50 +04:00
}
2020-01-31 02:29:06 +03:00
// Type switch allows switching on the type of something instead of value
var data interface { }
data = ""
switch c := data . ( type ) {
case string :
fmt . Println ( c , "is a string" )
case int64 :
fmt . Printf ( "%d is an int64\n" , c )
default :
// all other cases
}
2014-07-16 02:28:50 +04:00
// Like if, for doesn't use parens either.
// Variables declared in for and if are local to their scope.
for x := 0 ; x < 3 ; x ++ { // ++ is a statement.
fmt . Println ( "iteration" , x )
}
// x == 42 here.
// For is the only loop statement in Go, but it has alternate forms.
for { // Infinite loop.
break // Just kidding.
continue // Unreached.
}
2014-08-05 00:23:24 +04:00
2014-08-08 00:43:59 +04:00
// You can use range to iterate over an array, a slice, a string, a map, or a channel.
// range returns one (channel) or two values (array, slice, string and map).
2014-08-05 00:23:24 +04:00
for key , value := range map [ string ] int { "one" : 1 , "two" : 2 , "three" : 3 } {
// for each pair in the map, print key and value
fmt . Printf ( "key=%s, value=%d\n" , key , value )
}
2016-10-31 20:08:32 +03:00
// If you only need the value, use the underscore as the key
for _ , name := range [ ] string { "Bob" , "Bill" , "Joe" } {
fmt . Printf ( "Hello, %s\n" , name )
}
2014-08-05 00:23:24 +04:00
2014-07-16 02:28:50 +04:00
// As with for, := in an if statement means to declare and assign
// y first, then test y > x.
if y := expensiveComputation ( ) ; y > x {
x = y
}
// Function literals are closures.
xBig := func ( ) bool {
return x > 10000 // References x declared above switch statement.
}
2016-06-04 10:26:18 +03:00
x = 99999
fmt . Println ( "xBig:" , xBig ( ) ) // true
2014-07-16 02:28:50 +04:00
x = 1.3e3 // This makes x == 1300
fmt . Println ( "xBig:" , xBig ( ) ) // false now.
// What's more is function literals may be defined and called inline,
// acting as an argument to function, as long as:
// a) function literal is called immediately (),
// b) result type matches expected type of argument.
fmt . Println ( "Add + double two numbers: " ,
func ( a , b int ) int {
return ( a + b ) * 2
} ( 10 , 2 ) ) // Called with args 10 and 2
2014-09-05 17:05:13 +04:00
// => Add + double two numbers: 24
2014-07-16 02:28:50 +04:00
// When you need it, you'll love it.
goto love
2013-08-13 21:52:13 +04:00
love :
2014-07-16 02:28:50 +04:00
learnFunctionFactory ( ) // func returning func is fun(3)(3)
learnDefer ( ) // A quick detour to an important keyword.
learnInterfaces ( ) // Good stuff coming up!
2013-08-13 21:52:13 +04:00
}
2014-07-02 16:37:15 +04:00
func learnFunctionFactory ( ) {
2014-07-16 02:28:50 +04:00
// Next two are equivalent, with second being more practical
fmt . Println ( sentenceFactory ( "summer" ) ( "A beautiful" , "day!" ) )
2014-07-02 16:37:15 +04:00
2014-07-16 02:28:50 +04:00
d := sentenceFactory ( "summer" )
fmt . Println ( d ( "A beautiful" , "day!" ) )
fmt . Println ( d ( "A lazy" , "afternoon!" ) )
2014-07-02 16:37:15 +04:00
}
2014-06-29 19:12:58 +04:00
// Decorators are common in other languages. Same can be done in Go
// with function literals that accept arguments.
2014-07-02 16:37:15 +04:00
func sentenceFactory ( mystring string ) func ( before , after string ) string {
2014-07-16 02:28:50 +04:00
return func ( before , after string ) string {
return fmt . Sprintf ( "%s %s %s" , before , mystring , after ) // new string
}
2014-06-29 19:12:58 +04:00
}
2014-02-03 00:11:15 +04:00
func learnDefer ( ) ( ok bool ) {
2018-10-09 20:29:19 +03:00
// A defer statement pushes a function call onto a list. The list of saved
// calls is executed AFTER the surrounding function returns.
2014-07-16 02:28:50 +04:00
defer fmt . Println ( "deferred statements execute in reverse (LIFO) order." )
defer fmt . Println ( "\nThis line is being printed first because" )
// Defer is commonly used to close a file, so the function closing the
// file stays close to the function opening the file.
return true
2014-02-03 00:11:15 +04:00
}
2013-08-14 01:12:54 +04:00
// Define Stringer as an interface type with one method, String.
2013-08-13 21:52:13 +04:00
type Stringer interface {
2014-07-16 02:28:50 +04:00
String ( ) string
2013-08-13 21:52:13 +04:00
}
2013-08-14 01:12:54 +04:00
// Define pair as a struct with two fields, ints named x and y.
2013-08-13 21:52:13 +04:00
type pair struct {
2014-07-16 02:28:50 +04:00
x , y int
2013-08-13 21:52:13 +04:00
}
2017-07-02 15:38:55 +03:00
// Define a method on type pair. Pair now implements Stringer because Pair has defined all the methods in the interface.
2013-08-14 01:12:54 +04:00
func ( p pair ) String ( ) string { // p is called the "receiver"
2014-07-16 02:28:50 +04:00
// Sprintf is another public function in package fmt.
// Dot syntax references fields of p.
return fmt . Sprintf ( "(%d, %d)" , p . x , p . y )
2013-08-13 21:52:13 +04:00
}
func learnInterfaces ( ) {
2014-09-05 17:05:13 +04:00
// Brace syntax is a "struct literal". It evaluates to an initialized
// struct. The := syntax declares and initializes p to this struct.
2014-07-16 02:28:50 +04:00
p := pair { 3 , 4 }
fmt . Println ( p . String ( ) ) // Call String method of p, of type pair.
var i Stringer // Declare i of interface type Stringer.
i = p // Valid because pair implements Stringer
2014-09-05 17:05:13 +04:00
// Call String method of i, of type Stringer. Output same as above.
2014-07-16 02:28:50 +04:00
fmt . Println ( i . String ( ) )
// Functions in the fmt package call the String method to ask an object
// for a printable representation of itself.
fmt . Println ( p ) // Output same as above. Println calls String method.
fmt . Println ( i ) // Output same as above.
learnVariadicParams ( "great" , "learning" , "here!" )
2014-01-31 03:47:55 +04:00
}
// Functions can have variadic parameters.
func learnVariadicParams ( myStrings ... interface { } ) {
2014-07-16 02:28:50 +04:00
// Iterate each value of the variadic.
2024-01-27 00:29:13 +03:00
// The underscore here is ignoring the index argument of the array.
2014-07-16 02:28:50 +04:00
for _ , param := range myStrings {
fmt . Println ( "param:" , param )
}
2014-04-16 18:06:58 +04:00
2014-07-16 02:28:50 +04:00
// Pass variadic value as a variadic parameter.
fmt . Println ( "params:" , fmt . Sprintln ( myStrings ... ) )
2013-08-14 06:59:19 +04:00
2014-07-16 02:28:50 +04:00
learnErrorHandling ( )
2013-08-13 21:52:13 +04:00
}
func learnErrorHandling ( ) {
2014-07-16 02:28:50 +04:00
// ", ok" idiom used to tell if something worked or not.
m := map [ int ] string { 3 : "three" , 4 : "four" }
if x , ok := m [ 1 ] ; ! ok { // ok will be false because 1 is not in the map.
fmt . Println ( "no one there" )
} else {
fmt . Print ( x ) // x would be the value, if it were in the map.
}
// An error value communicates not just "ok" but more about the problem.
if _ , err := strconv . Atoi ( "non-int" ) ; err != nil { // _ discards value
// prints 'strconv.ParseInt: parsing "non-int": invalid syntax'
fmt . Println ( err )
}
2014-09-05 17:05:13 +04:00
// We'll revisit interfaces a little later. Meanwhile,
2014-07-16 02:28:50 +04:00
learnConcurrency ( )
2013-08-13 21:52:13 +04:00
}
2013-08-14 01:12:54 +04:00
// c is a channel, a concurrency-safe communication object.
2013-08-13 21:52:13 +04:00
func inc ( i int , c chan int ) {
2014-07-16 02:28:50 +04:00
c <- i + 1 // <- is the "send" operator when a channel appears on the left.
2013-08-13 21:52:13 +04:00
}
// We'll use inc to increment some numbers concurrently.
func learnConcurrency ( ) {
2014-09-05 17:05:13 +04:00
// Same make function used earlier to make a slice. Make allocates and
2014-07-16 02:28:50 +04:00
// initializes slices, maps, and channels.
c := make ( chan int )
2014-09-05 17:05:13 +04:00
// Start three concurrent goroutines. Numbers will be incremented
2014-07-16 02:28:50 +04:00
// concurrently, perhaps in parallel if the machine is capable and
2014-09-05 17:05:13 +04:00
// properly configured. All three send to the same channel.
2014-07-16 02:28:50 +04:00
go inc ( 0 , c ) // go is a statement that starts a new goroutine.
go inc ( 10 , c )
go inc ( - 805 , c )
// Read three results from the channel and print them out.
// There is no telling in what order the results will arrive!
fmt . Println ( <- c , <- c , <- c ) // channel on right, <- is "receive" operator.
cs := make ( chan string ) // Another channel, this one handles strings.
ccs := make ( chan chan string ) // A channel of string channels.
go func ( ) { c <- 84 } ( ) // Start a new goroutine just to send a value.
go func ( ) { cs <- "wordy" } ( ) // Again, for cs this time.
// Select has syntax like a switch statement but each case involves
2014-09-05 17:05:13 +04:00
// a channel operation. It selects a case at random out of the cases
2014-07-16 02:28:50 +04:00
// that are ready to communicate.
select {
case i := <- c : // The value received can be assigned to a variable,
fmt . Printf ( "it's a %T" , i )
case <- cs : // or the value received can be discarded.
fmt . Println ( "it's a string" )
case <- ccs : // Empty channel, not ready for communication.
fmt . Println ( "didn't happen." )
}
2014-09-05 17:05:13 +04:00
// At this point a value was taken from either c or cs. One of the two
2014-07-16 02:28:50 +04:00
// goroutines started above has completed, the other will remain blocked.
learnWebProgramming ( ) // Go does it. You want to do it too.
2013-08-13 21:52:13 +04:00
}
2013-08-14 01:12:54 +04:00
// A single function from package http starts a web server.
2013-08-13 21:52:13 +04:00
func learnWebProgramming ( ) {
2014-07-02 16:55:33 +04:00
2014-07-16 02:28:50 +04:00
// First parameter of ListenAndServe is TCP address to listen to.
// Second parameter is an interface, specifically http.Handler.
go func ( ) {
err := http . ListenAndServe ( ":8080" , pair { } )
fmt . Println ( err ) // don't ignore errors
} ( )
2014-07-02 16:55:33 +04:00
2014-07-16 02:28:50 +04:00
requestServer ( )
2013-08-13 21:52:13 +04:00
}
2013-08-14 01:12:54 +04:00
// Make pair an http.Handler by implementing its only method, ServeHTTP.
2013-08-13 21:52:13 +04:00
func ( p pair ) ServeHTTP ( w http . ResponseWriter , r * http . Request ) {
2014-07-16 02:28:50 +04:00
// Serve data with a method of http.ResponseWriter.
w . Write ( [ ] byte ( "You learned Go in Y minutes!" ) )
2013-08-13 21:52:13 +04:00
}
2014-07-02 16:55:33 +04:00
func requestServer ( ) {
2014-07-16 02:28:50 +04:00
resp , err := http . Get ( "http://localhost:8080" )
fmt . Println ( err )
defer resp . Body . Close ( )
body , err := ioutil . ReadAll ( resp . Body )
fmt . Printf ( "\nWebserver said: `%s`" , string ( body ) )
2014-07-02 16:55:33 +04:00
}
2013-08-13 21:52:13 +04:00
` ` `
# # Further Reading
2024-04-01 10:35:55 +03:00
The root of all things Go is the [ official Go web site ] ( https : //go.dev/).
2013-08-13 21:52:13 +04:00
There you can follow the tutorial , play interactively , and read lots .
2024-04-01 10:35:55 +03:00
Aside from a tour , [ the docs ] ( https : //go.dev/doc/) contain information on
2015-10-09 06:24:25 +03:00
how to write clean and effective Go code , package and command docs , and release history .
2013-08-13 21:52:13 +04:00
2024-04-01 10:35:55 +03:00
The [ Go language specification ] ( https : //go.dev/ref/spec) itself is highly recommended. It's easy to read
2013-08-13 21:52:13 +04:00
and amazingly short ( as language definitions go these days . )
2024-04-01 10:35:55 +03:00
You can play around with the code on [ Go playground ] ( https : //go.dev/play/p/tnWMjr16Mm). Try to change it and run it from your browser! Note that you can use [https://go.dev/play/](https://go.dev/play/) as a [REPL](https://en.wikipedia.org/wiki/Read-eval-print_loop) to test things and code in your browser, without even installing Go.
2014-08-05 11:03:21 +04:00
2013-09-05 07:46:45 +04:00
On the reading list for students of Go is the [ source code to the standard
2024-04-01 10:35:55 +03:00
library ] ( https : //go.dev/src/). Comprehensively documented, it
2013-09-05 07:46:45 +04:00
demonstrates the best of readable and understandable Go , Go style , and Go
2014-09-05 17:05:13 +04:00
idioms . Or you can click on a function name in [ the
2024-04-01 10:35:55 +03:00
documentation ] ( https : //go.dev/pkg/) and the source code comes up!
2013-08-13 21:52:13 +04:00
2014-05-12 00:33:08 +04:00
Another great resource to learn Go is [ Go by example ] ( https : //gobyexample.com/).
2015-10-14 09:33:05 +03:00
2020-02-27 14:50:39 +03:00
There are many excellent conference talks and video tutorials on Go available on YouTube , and here are three playlists of the very best , tailored for beginners , intermediate , and advanced Gophers respectively :
2022-01-03 18:50:15 +03:00
- [ Golang University 101 ] ( https : //www.youtube.com/playlist?list=PLEcwzBXTPUE9V1o8mZdC9tNnRZaTgI-1P) introduces fundamental Go concepts and shows you how to use the Go tools to create and manage Go code
- [ Golang University 201 ] ( https : //www.youtube.com/playlist?list=PLEcwzBXTPUE_5m_JaMXmGEFgduH8EsuTs) steps it up a notch, explaining important techniques like testing, web services, and APIs
2022-03-04 06:29:48 +03:00
- [ Golang University 301 ] ( https : //www.youtube.com/playlist?list=PLEcwzBXTPUE8KvXRFmmfPEUmKoy9LfmAf) dives into more advanced topics like the Go scheduler, implementation of maps and channels, and optimisation techniques
2020-02-23 15:44:28 +03:00
2015-10-14 09:33:05 +03:00
Go Mobile adds support for mobile platforms ( Android and iOS ) . You can write all - Go native mobile apps or write a library that contains bindings from a Go package , which can be invoked via Java ( Android ) and Objective - C ( iOS ) . Check out the [ Go Mobile page ] ( https : //github.com/golang/go/wiki/Mobile) for more information.