Callum Slater

Callum Slater

1565838920

A beginners guide to writing Go packages

Originally published by Gopher Guides at https://www.digitalocean.com

A package is made up of Go files that live in the same directory and have the same package statement at the beginning. You can include additional functionality from packages to make your programs more sophisticated. Some packages are available through the Go Standard Library and are therefore installed with your Go installation. Others can be installed with Go’s go get command. You can also build your own Go packages by creating Go files in the same directory across which you want to share code by using the necessary package statement.

This tutorial will guide you through writing Go packages for use within other programming files.

Writing and Importing Packages

Writing a package is just like writing any other Go file. Packages can contain definitions of functions, types, and variables that can then be used in other Go programs.

Before we create a new package, we need to be in our Go workspace. This is typically under our gopath. For the example, in this tutorial we will call the package greet. To do this, we've created a directory called greet in our gopath under our project space. If our organization were gopherguides, and we wanted to create the greet package under the organization while using Github as our code repository, then our directory would look like this:

└── $GOPATH
   └── src
       └── github.com
           └── gopherguides

The greet directory is within the gopherguides directory:

└── $GOPATH
   └── src
       └── github.com
           └── gopherguides
               └── greet

Finally, we can add the first file in our directory. It is considered common practice that the primary or entry point file in a package is named after the name of the directory. In this case, we would create a file called greet.go inside the greet directory:

└── $GOPATH
   └── src
       └── github.com
           └── gopherguides
               └── greet
                   └── greet.go

With the file created, we can begin to write our code that we want to reuse or share across projects. In this case, we will create a function called Hello that prints out Hello World.

Open your greet.go file in your text editor and add the following code:

greet.go

package greet

import “fmt”

func Hello() {
   fmt.Println(“Hello, World!”)
}

Let’s break this first file down. The first line of each file needs the name of the package that you are working in. Since you’re in the greet package, you use the package keyword followed by the name of the package:

package greet

This will tell the compiler to treat everything in the file as being part of the greet package.

Next you declare any other packages you need to use with the import statement. You’re only using one in this file—the fmt package:

import “fmt”

Lastly, you create the function Hello. It will use the fmt package to print out Hello, World!:

func Hello() {
   fmt.Println(“Hello, World!”)
}

Now that you’ve written the greet package, you can use it in any other package you create. Let’s create a new package in which you’ll use your greet package.

You’re going to create a package called example, which means you need a directory called example. Create this package in your gopherguides organization, so the directory structure looks like so:

└── $GOPATH
   └── src
       └── github.com
           └── gopherguides
                   └── example

Now that you have your directory for your new package, you can create the entry point file. Because this is going to be an executable program, it is considered best practice to name the entry point file main.go:

└── $GOPATH
   └── src
       └── github.com
           └── gopherguides
               └── example
                   └── main.go

In your text editor, open main.go and add the following code to call the greet package:

main.go

package main

import “github.com/gopherguides/greet

func main() {
   greet.Hello()
}

Because you’re importing a package, you need to call the function by referencing the package name in dot notation. Dot notation is the practice of putting a period . between the name of the package you are using and the resource within that package that you want to use. For instance, in your greet package, you have the Hello function as a resource. If you want to call that resource, you use the dot notation of greet.Hello().

Now, you can open your terminal and run the program on the command line:

go run main.go

When you do, you’ll receive the following output:

Output
Hello, World!

To see how you can use variables in a package, let’s add a variable definition in your greet.go file:

greet.go

package greet

import “fmt”

var Shark = “Sammy”

func Hello() {
   fmt.Println(“Hello, World!”)
}

Next, open your main.go file and add the following highlighted line to call the variable from greet.go in a fmt.Println() function:

main.go

package main

import (
   “fmt”

   “github.com/gopherguides/greet
)

func main() {
   greet.Hello()

   fmt.Println(greet.Shark)
}

Once you run the program again:

go run main.go

You’ll receive the following output:

Output
Hello, World!
Sammy

Finally, let’s also define a type in the greet.go file. You’ll create the type Octopus with name and color fields, and a function that will print out the fields when called:

greet.go

package greet

import “fmt”

var Shark = “Sammy”

type Octopus struct {
   Name string
   Color string
}

func (o Octopus) String() string {
   return fmt.Sprintf(“The octopus’s name is %q and is the color %s.”, o.Name, o.Color)
}

func Hello() {
   fmt.Println(“Hello, World!”)
}

Open main.go to create an instance of that type at the end of the file:

main.go

package main

import (
   “fmt”

   “github.com/gopherguides/greet
)

func main() {
   greet.Hello()

   fmt.Println(greet.Shark)

   oct := greet.Octopus{
       Name: “Jesse”,
       Color: “orange”,
   }

   fmt.Println(oct.String())
}

Once you’ve created an instance of Octopus type with oct := greet.Octopus, you can access the functions and fields of the type within the main.go file’s namespace. This lets you write oct.String() on the last line without invoking greet. You could also, for example, call one of the types fields such as oct.Color without referencing the name of the greet package.

The String method on the Octopus type uses the fmt.Sprintf function to create a sentence, and returns the result, a string, to the caller (in this case, your main program).

When you run the program, you’ll receive the following output:

go run main.go


Output
Hello, World!
Sammy

The octopus’s name is “Jesse” and is the color orange.

By creating the String method on Octopus, you now have a reusable way to print out information about your custom type. If you want to change the behavior of this method in the future, you only have to edit this one method.

Exported Code

You may have noticed that all of the declarations in the greet.go file you called were capitalized. Go does not have the concept of public, private, or protected modifiers like other languages do. External visibility is controlled by capitalization. Types, variables, functions, and so on, that start with a capital letter are available, publicly, outside the current package. A symbol that is visible outside its package is considered to be exported.

If you add a new method to Octopus called reset, you can call it from within the greet package, but not from your main.go file, which is outside the greet package:

greet.go

package greet

import “fmt”

var Shark = “Sammy”

type Octopus struct {
   Name string
   Color string
}

func (o Octopus) String() string {
   return fmt.Sprintf(“The octopus’s name is %q and is the color %s.”, o.Name, o.Color)
}

func (o Octopus) reset() {
   o.Name = “”
   o.Color = “”
}

func Hello() {
   fmt.Println(“Hello, World!”)
}

If you try to call reset from the main.go file:

main.go

package main

import (
   “fmt”

   “github.com/gopherguides/greet
)

func main() {
   greet.Hello()

   fmt.Println(greet.Shark)

   oct := greet.Octopus{
       Name: “Jesse”,
       Color: “orange”,
   }

   fmt.Println(oct.String())

   oct.reset()
}

You’ll receive the following compilation error:

Output
oct.reset undefined (cannot refer to unexported field or method greet.Octopus.reset)

To export the reset functionality from Octopus, capitalize the R in reset:

greet.go

package greet

import “fmt”

var Shark = “Sammy”

type Octopus struct {
   Name string
   Color string
}

func (o Octopus) String() string {
   return fmt.Sprintf(“The octopus’s name is %q and is the color %s.”, o.Name, o.Color)
}

func (o Octopus) Reset() {
   o.Name = “”
   o.Color = “”
}

func Hello() {
   fmt.Println(“Hello, World!”)
}

As a result you can call Reset from your other package without getting an error:

main.go

package main

import (
   “fmt”

   “github.com/gopherguides/greet
)

func main() {
   greet.Hello()

   fmt.Println(greet.Shark)

   oct := greet.Octopus{
       Name: “Jesse”,
       Color: “orange”,
   }

   fmt.Println(oct.String())

   oct.Reset()

   fmt.Println(oct.String())
}

Now if you run the program:

go run main.go

You will receive the following output:

Output
Hello, World!
Sammy
The octopus’s name is “Jesse” and is the color orange
The octopus’s name is “” and is the color .

By calling Reset, you cleared out all the information in the Name and Color fields. When you call the String method, it will print nothing where Name and Color normally appear because the fields are now empty.

Conclusion

Writing a Go package is the same as writing any other Go file, but placing it in another directory allows you to isolate the code to be reused elsewhere. This tutorial covered how to write definitions within a package, demonstrated how to make use of those definitions within another Go programming file, and explained the options for where to keep the package in order to access it.

Thanks for reading

If you liked this post, share it with all of your programming buddies!

Follow me on Facebook | Twitter

Further reading about Go Programming

Learn How To Code: Google’s Go (golang) Programming Language

Go: The Complete Developer’s Guide (Golang)

Build Realtime Apps | React Js, Golang & RethinkDB

Go Programming Language Tutorial | Golang Tutorial For Beginners | Go / Golang Crash Course

Google’s Go Essentials For Node.js / JavaScript Developers

Moving from NodeJS to Go

Learn Go Programming - Golang Tutorial for Beginners

A guide to Golang e-commerce


#go #web-development #web-service

What is GEEK

Buddha Community

A beginners guide to writing Go packages
Fannie  Zemlak

Fannie Zemlak

1599854400

What's new in the go 1.15

Go announced Go 1.15 version on 11 Aug 2020. Highlighted updates and features include Substantial improvements to the Go linker, Improved allocation for small objects at high core counts, X.509 CommonName deprecation, GOPROXY supports skipping proxies that return errors, New embedded tzdata package, Several Core Library improvements and more.

As Go promise for maintaining backward compatibility. After upgrading to the latest Go 1.15 version, almost all existing Golang applications or programs continue to compile and run as older Golang version.

#go #golang #go 1.15 #go features #go improvement #go package #go new features

Generis: Versatile Go Code Generator

Generis

Versatile Go code generator.

Description

Generis is a lightweight code preprocessor adding the following features to the Go language :

  • Generics.
  • Free-form macros.
  • Conditional compilation.
  • HTML templating.
  • Allman style conversion.

Sample

package main;

// -- IMPORTS

import (
    "html"
    "io"
    "log"
    "net/http"
    "net/url"
    "strconv"
    );

// -- DEFINITIONS

#define DebugMode
#as true

// ~~

#define HttpPort
#as 8080

// ~~

#define WriteLine( {{text}} )
#as log.Println( {{text}} )

// ~~

#define local {{variable}} : {{type}};
#as var {{variable}} {{type}};

// ~~

#define DeclareStack( {{type}}, {{name}} )
#as
    // -- TYPES

    type {{name}}Stack struct
    {
        ElementArray []{{type}};
    }

    // -- INQUIRIES

    func ( stack * {{name}}Stack ) IsEmpty(
        ) bool
    {
        return len( stack.ElementArray ) == 0;
    }

    // -- OPERATIONS

    func ( stack * {{name}}Stack ) Push(
        element {{type}}
        )
    {
        stack.ElementArray = append( stack.ElementArray, element );
    }

    // ~~

    func ( stack * {{name}}Stack ) Pop(
        ) {{type}}
    {
        local
            element : {{type}};

        element = stack.ElementArray[ len( stack.ElementArray ) - 1 ];

        stack.ElementArray = stack.ElementArray[ : len( stack.ElementArray ) - 1 ];

        return element;
    }
#end

// ~~

#define DeclareStack( {{type}} )
#as DeclareStack( {{type}}, {{type:PascalCase}} )

// -- TYPES

DeclareStack( string )
DeclareStack( int32 )

// -- FUNCTIONS

func HandleRootPage(
    response_writer http.ResponseWriter,
    request * http.Request
    )
{
    local
        boolean : bool;
    local
        natural : uint;
    local
        integer : int;
    local
        real : float64;
    local
        escaped_html_text,
        escaped_url_text,
        text : string;
    local
        integer_stack : Int32Stack;

    boolean = true;
    natural = 10;
    integer = 20;
    real = 30.0;
    text = "text";
    escaped_url_text = "&escaped text?";
    escaped_html_text = "<escaped text/>";

    integer_stack.Push( 10 );
    integer_stack.Push( 20 );
    integer_stack.Push( 30 );

    #write response_writer
        <!DOCTYPE html>
        <html lang="en">
            <head>
                <meta charset="utf-8">
                <title><%= request.URL.Path %></title>
            </head>
            <body>
                <% if ( boolean ) { %>
                    <%= "URL : " + request.URL.Path %>
                    <br/>
                    <%@ natural %>
                    <%# integer %>
                    <%& real %>
                    <br/>
                    <%~ text %>
                    <%^ escaped_url_text %>
                    <%= escaped_html_text %>
                    <%= "<%% ignored %%>" %>
                    <%% ignored %%>
                <% } %>
                <br/>
                Stack :
                <br/>
                <% for !integer_stack.IsEmpty() { %>
                    <%# integer_stack.Pop() %>
                <% } %>
            </body>
        </html>
    #end
}

// ~~

func main()
{
    http.HandleFunc( "/", HandleRootPage );

    #if DebugMode
        WriteLine( "Listening on http://localhost:HttpPort" );
    #end

    log.Fatal(
        http.ListenAndServe( ":HttpPort", nil )
        );
}

Syntax

#define directive

Constants and generic code can be defined with the following syntax :

#define old code
#as new code

#define old code
#as
    new
    code
#end

#define
    old
    code
#as new code

#define
    old
    code
#as
    new
    code
#end

#define parameter

The #define directive can contain one or several parameters :

{{variable name}} : hierarchical code (with properly matching brackets and parentheses)
{{variable name#}} : statement code (hierarchical code without semicolon)
{{variable name$}} : plain code
{{variable name:boolean expression}} : conditional hierarchical code
{{variable name#:boolean expression}} : conditional statement code
{{variable name$:boolean expression}} : conditional plain code

They can have a boolean expression to require they match specific conditions :

HasText text
HasPrefix prefix
HasSuffix suffix
HasIdentifier text
false
true
!expression
expression && expression
expression || expression
( expression )

The #define directive must not start or end with a parameter.

#as parameter

The #as directive can use the value of the #define parameters :

{{variable name}}
{{variable name:filter function}}
{{variable name:filter function:filter function:...}}

Their value can be changed through one or several filter functions :

LowerCase
UpperCase
MinorCase
MajorCase
SnakeCase
PascalCase
CamelCase
RemoveComments
RemoveBlanks
PackStrings
PackIdentifiers
ReplacePrefix old_prefix new_prefix
ReplaceSuffix old_suffix new_suffix
ReplaceText old_text new_text
ReplaceIdentifier old_identifier new_identifier
AddPrefix prefix
AddSuffix suffix
RemovePrefix prefix
RemoveSuffix suffix
RemoveText text
RemoveIdentifier identifier

#if directive

Conditional code can be defined with the following syntax :

#if boolean expression
    #if boolean expression
        ...
    #else
        ...
    #end
#else
    #if boolean expression
        ...
    #else
        ...
    #end
#end

The boolean expression can use the following operators :

false
true
!expression
expression && expression
expression || expression
( expression )

#write directive

Templated HTML code can be sent to a stream writer using the following syntax :

#write writer expression
    <% code %>
    <%@ natural expression %>
    <%# integer expression %>
    <%& real expression %>
    <%~ text expression %>
    <%= escaped text expression %>
    <%! removed content %>
    <%% ignored tags %%>
#end

Limitations

  • There is no operator precedence in boolean expressions.
  • The --join option requires to end the statements with a semicolon.
  • The #writer directive is only available for the Go language.

Installation

Install the DMD 2 compiler (using the MinGW setup option on Windows).

Build the executable with the following command line :

dmd -m64 generis.d

Command line

generis [options]

Options

--prefix # : set the command prefix
--parse INPUT_FOLDER/ : parse the definitions of the Generis files in the input folder
--process INPUT_FOLDER/ OUTPUT_FOLDER/ : reads the Generis files in the input folder and writes the processed files in the output folder
--trim : trim the HTML templates
--join : join the split statements
--create : create the output folders if needed
--watch : watch the Generis files for modifications
--pause 500 : time to wait before checking the Generis files again
--tabulation 4 : set the tabulation space count
--extension .go : generate files with this extension

Examples

generis --process GS/ GO/

Reads the Generis files in the GS/ folder and writes Go files in the GO/ folder.

generis --process GS/ GO/ --create

Reads the Generis files in the GS/ folder and writes Go files in the GO/ folder, creating the output folders if needed.

generis --process GS/ GO/ --create --watch

Reads the Generis files in the GS/ folder and writes Go files in the GO/ folder, creating the output folders if needed and watching the Generis files for modifications.

generis --process GS/ GO/ --trim --join --create --watch

Reads the Generis files in the GS/ folder and writes Go files in the GO/ folder, trimming the HTML templates, joining the split statements, creating the output folders if needed and watching the Generis files for modifications.

Version

2.0

Author: Senselogic
Source Code: https://github.com/senselogic/GENERIS 
License: View license

#go #golang #code 

Callum Slater

Callum Slater

1565838920

A beginners guide to writing Go packages

Originally published by Gopher Guides at https://www.digitalocean.com

A package is made up of Go files that live in the same directory and have the same package statement at the beginning. You can include additional functionality from packages to make your programs more sophisticated. Some packages are available through the Go Standard Library and are therefore installed with your Go installation. Others can be installed with Go’s go get command. You can also build your own Go packages by creating Go files in the same directory across which you want to share code by using the necessary package statement.

This tutorial will guide you through writing Go packages for use within other programming files.

Writing and Importing Packages

Writing a package is just like writing any other Go file. Packages can contain definitions of functions, types, and variables that can then be used in other Go programs.

Before we create a new package, we need to be in our Go workspace. This is typically under our gopath. For the example, in this tutorial we will call the package greet. To do this, we've created a directory called greet in our gopath under our project space. If our organization were gopherguides, and we wanted to create the greet package under the organization while using Github as our code repository, then our directory would look like this:

└── $GOPATH
   └── src
       └── github.com
           └── gopherguides

The greet directory is within the gopherguides directory:

└── $GOPATH
   └── src
       └── github.com
           └── gopherguides
               └── greet

Finally, we can add the first file in our directory. It is considered common practice that the primary or entry point file in a package is named after the name of the directory. In this case, we would create a file called greet.go inside the greet directory:

└── $GOPATH
   └── src
       └── github.com
           └── gopherguides
               └── greet
                   └── greet.go

With the file created, we can begin to write our code that we want to reuse or share across projects. In this case, we will create a function called Hello that prints out Hello World.

Open your greet.go file in your text editor and add the following code:

greet.go

package greet

import “fmt”

func Hello() {
   fmt.Println(“Hello, World!”)
}

Let’s break this first file down. The first line of each file needs the name of the package that you are working in. Since you’re in the greet package, you use the package keyword followed by the name of the package:

package greet

This will tell the compiler to treat everything in the file as being part of the greet package.

Next you declare any other packages you need to use with the import statement. You’re only using one in this file—the fmt package:

import “fmt”

Lastly, you create the function Hello. It will use the fmt package to print out Hello, World!:

func Hello() {
   fmt.Println(“Hello, World!”)
}

Now that you’ve written the greet package, you can use it in any other package you create. Let’s create a new package in which you’ll use your greet package.

You’re going to create a package called example, which means you need a directory called example. Create this package in your gopherguides organization, so the directory structure looks like so:

└── $GOPATH
   └── src
       └── github.com
           └── gopherguides
                   └── example

Now that you have your directory for your new package, you can create the entry point file. Because this is going to be an executable program, it is considered best practice to name the entry point file main.go:

└── $GOPATH
   └── src
       └── github.com
           └── gopherguides
               └── example
                   └── main.go

In your text editor, open main.go and add the following code to call the greet package:

main.go

package main

import “github.com/gopherguides/greet

func main() {
   greet.Hello()
}

Because you’re importing a package, you need to call the function by referencing the package name in dot notation. Dot notation is the practice of putting a period . between the name of the package you are using and the resource within that package that you want to use. For instance, in your greet package, you have the Hello function as a resource. If you want to call that resource, you use the dot notation of greet.Hello().

Now, you can open your terminal and run the program on the command line:

go run main.go

When you do, you’ll receive the following output:

Output
Hello, World!

To see how you can use variables in a package, let’s add a variable definition in your greet.go file:

greet.go

package greet

import “fmt”

var Shark = “Sammy”

func Hello() {
   fmt.Println(“Hello, World!”)
}

Next, open your main.go file and add the following highlighted line to call the variable from greet.go in a fmt.Println() function:

main.go

package main

import (
   “fmt”

   “github.com/gopherguides/greet
)

func main() {
   greet.Hello()

   fmt.Println(greet.Shark)
}

Once you run the program again:

go run main.go

You’ll receive the following output:

Output
Hello, World!
Sammy

Finally, let’s also define a type in the greet.go file. You’ll create the type Octopus with name and color fields, and a function that will print out the fields when called:

greet.go

package greet

import “fmt”

var Shark = “Sammy”

type Octopus struct {
   Name string
   Color string
}

func (o Octopus) String() string {
   return fmt.Sprintf(“The octopus’s name is %q and is the color %s.”, o.Name, o.Color)
}

func Hello() {
   fmt.Println(“Hello, World!”)
}

Open main.go to create an instance of that type at the end of the file:

main.go

package main

import (
   “fmt”

   “github.com/gopherguides/greet
)

func main() {
   greet.Hello()

   fmt.Println(greet.Shark)

   oct := greet.Octopus{
       Name: “Jesse”,
       Color: “orange”,
   }

   fmt.Println(oct.String())
}

Once you’ve created an instance of Octopus type with oct := greet.Octopus, you can access the functions and fields of the type within the main.go file’s namespace. This lets you write oct.String() on the last line without invoking greet. You could also, for example, call one of the types fields such as oct.Color without referencing the name of the greet package.

The String method on the Octopus type uses the fmt.Sprintf function to create a sentence, and returns the result, a string, to the caller (in this case, your main program).

When you run the program, you’ll receive the following output:

go run main.go


Output
Hello, World!
Sammy

The octopus’s name is “Jesse” and is the color orange.

By creating the String method on Octopus, you now have a reusable way to print out information about your custom type. If you want to change the behavior of this method in the future, you only have to edit this one method.

Exported Code

You may have noticed that all of the declarations in the greet.go file you called were capitalized. Go does not have the concept of public, private, or protected modifiers like other languages do. External visibility is controlled by capitalization. Types, variables, functions, and so on, that start with a capital letter are available, publicly, outside the current package. A symbol that is visible outside its package is considered to be exported.

If you add a new method to Octopus called reset, you can call it from within the greet package, but not from your main.go file, which is outside the greet package:

greet.go

package greet

import “fmt”

var Shark = “Sammy”

type Octopus struct {
   Name string
   Color string
}

func (o Octopus) String() string {
   return fmt.Sprintf(“The octopus’s name is %q and is the color %s.”, o.Name, o.Color)
}

func (o Octopus) reset() {
   o.Name = “”
   o.Color = “”
}

func Hello() {
   fmt.Println(“Hello, World!”)
}

If you try to call reset from the main.go file:

main.go

package main

import (
   “fmt”

   “github.com/gopherguides/greet
)

func main() {
   greet.Hello()

   fmt.Println(greet.Shark)

   oct := greet.Octopus{
       Name: “Jesse”,
       Color: “orange”,
   }

   fmt.Println(oct.String())

   oct.reset()
}

You’ll receive the following compilation error:

Output
oct.reset undefined (cannot refer to unexported field or method greet.Octopus.reset)

To export the reset functionality from Octopus, capitalize the R in reset:

greet.go

package greet

import “fmt”

var Shark = “Sammy”

type Octopus struct {
   Name string
   Color string
}

func (o Octopus) String() string {
   return fmt.Sprintf(“The octopus’s name is %q and is the color %s.”, o.Name, o.Color)
}

func (o Octopus) Reset() {
   o.Name = “”
   o.Color = “”
}

func Hello() {
   fmt.Println(“Hello, World!”)
}

As a result you can call Reset from your other package without getting an error:

main.go

package main

import (
   “fmt”

   “github.com/gopherguides/greet
)

func main() {
   greet.Hello()

   fmt.Println(greet.Shark)

   oct := greet.Octopus{
       Name: “Jesse”,
       Color: “orange”,
   }

   fmt.Println(oct.String())

   oct.Reset()

   fmt.Println(oct.String())
}

Now if you run the program:

go run main.go

You will receive the following output:

Output
Hello, World!
Sammy
The octopus’s name is “Jesse” and is the color orange
The octopus’s name is “” and is the color .

By calling Reset, you cleared out all the information in the Name and Color fields. When you call the String method, it will print nothing where Name and Color normally appear because the fields are now empty.

Conclusion

Writing a Go package is the same as writing any other Go file, but placing it in another directory allows you to isolate the code to be reused elsewhere. This tutorial covered how to write definitions within a package, demonstrated how to make use of those definitions within another Go programming file, and explained the options for where to keep the package in order to access it.

Thanks for reading

If you liked this post, share it with all of your programming buddies!

Follow me on Facebook | Twitter

Further reading about Go Programming

Learn How To Code: Google’s Go (golang) Programming Language

Go: The Complete Developer’s Guide (Golang)

Build Realtime Apps | React Js, Golang & RethinkDB

Go Programming Language Tutorial | Golang Tutorial For Beginners | Go / Golang Crash Course

Google’s Go Essentials For Node.js / JavaScript Developers

Moving from NodeJS to Go

Learn Go Programming - Golang Tutorial for Beginners

A guide to Golang e-commerce


#go #web-development #web-service

What You Can Learn about Setting from Classic Sitcoms

Giving your novel a strong sense of place is vital to doing your part to engage the readers without confusing or frustrating them. Setting is a big part of this (though not the whole enchilada — there is also social context and historic period), and I often find writing students and consulting clients erring on one of two extremes.

**Either: **Every scene is set in a different, elaborately-described place from the last. This leads to confusion (and possibly exhaustion and impatience) for the reader, because they have no sense of what they need to actually pay attention to for later and what’s just…there. Are the details of that forest in chapter 2 important? Will I ever be back in this castle again? Is there a reason for this character to be in this particular room versus the one she was in the last time I saw her? Who knows!

Or: There are few or no clues at all as to where the characters are in a scene. What’s in the room? Are they even in a room? Are there other people in th — ope, yes, there are, someone just materialized, what is happening? This all leads to the dreaded “brains in jars” syndrome. That is, characters are only their thoughts and words, with no grounding in the space-time continuum. No one seems to be in a place, in a body, at a time of day.

Everything aspect of writing a novel comes with its difficulties, and there are a lot of moving pieces to manage and deploy in the right balance. When you’re a newer writer, especially, there’s something to be said for keeping things simple until you have a handle on how to manage the arc and scope of a novel-length work. And whether you tend to overdo settings or underdo them, you can learn something from TV, especially classic sitcoms.

Your basic “live studio audience” sitcoms are performed and filmed on sets built inside studios vs. on location. This helps keep production expenses in check and helps the viewer feel at home — there’s a reliable and familiar container to hold the story of any given episode. The writers on the show don’t have to reinvent the wheel with every script.

Often, a show will have no more than two or three basic sets that are used episode to episode, and then a few other easily-understood sets (characters’ workplaces, restaurants, streets scenes) are also used regularly but not every episode.

#creative-writing #writing-exercise #writing-craft #writing #writing-tips #machine learning

Send Email in Golang using Go Mail Package | Emails in Go

Send an email with Golang using a popular package Gomail.

Gomail is a simple and efficient package to send emails. It is well tested and documented.
Gomail can only send emails using an SMTP server. But the API is flexible and it is easy to implement other methods for sending emails using a local Postfix, an API, etc.
Install Gomail: go get gopkg.in/gomail.v2

#golang #Gomail #emailGolang #GolangEMail

#golang #go mail package #go