package
0.0.0-20200526015148-b343531734ec
Repository: https://github.com/fakorede/learning-golang.git
Documentation: pkg.go.dev

# Packages

No description provided by the author

# README

An Interface is a custom type that is used to specify a set of one or more method signatures. Interfaces are abstract, so you we're not allowed to create an instance of the interface.

But you are allowed to create a variable of an interface type and this variable can be assigned with a concrete type value that has the methods the interface requires. Or in other words, the interface is a collection of methods as well as it is a custom type.

Below is the syntax for creating an Interface

// Identifiable : Identifiable interface
type Identifiable interface {

}

In an Interface we can have functions and we don't have to explicitly use the func keyword because its the only thing we can have in there.

Any type that implements the Identifiable interface is of type Identifiable

A Struct is a user-defined type that contains a collection of named fields/properties. It is used to group related data together to form a single unit. Any real-world entity that has a set of properties can be represented using a struct.

If you’re coming from an object-oriented background, you can think of a struct as a lightweight class that supports composition but not inheritance.

Below is the syntax for creating a Struct

// Person : Person struct
type Person struct {

}

Person implicitly inherits the Identifiable interface by implementing the ID method.

// ID : method of the Identifiable interface implemented by Person
func (p Person) ID() string {
	return "12345"
}

We can define Private Fields on the Person struct:

// Person : Person struct
type Person struct {
	firstName string
	lastName  string
}

We define a Constructor which sets the fields of the Person struct:

// NewPerson : returns the Person object
func NewPerson(firstName, lastName string) Person {
	return Person{
		firstName: firstName,
		lastName:  lastName,
	}
}

We define a FullName method on the Person struct to a formatted version of the fields accessible.

// FullName : returns the firstName and lastName fields of the Person struct
func (p Person) FullName() string {
	return fmt.Sprintf("%s %s", p.firstName, p.lastName)
}

To Change the State of the Struct, we have to implement a setter

// Person : Person struct
type Person struct {
	...
	twitterHandler string
}
// SetTwitterHandler : sets the TwitterHandler field on the Person struct
func (p Person) SetTwitterHandler(handler string) error {
	if len(handler) == 0 {
		p.twitterHandler = handler
	} else if !strings.HasPrefix(handler, "@") {
		return errors.New("twitter handler must start with an @ symbol")
	}

	p.twitterHandler = handler

	return nil

}

And then create a getter to return the data:

// TwitterHandler : returns the TwitterHandler field on the Person struct
func (p Person) TwitterHandler() string {
	return p.twitterHandler
}

Note: When changing state, we have to make use of a Pointer receiver to track and make our data uniform:

// SetTwitterHandler : sets the TwitterHandler field on the Person struct
func (p *Person) SetTwitterHandler(handler string) error {
	...
}

In our main.go file, we can create a NewPerson access and access all the needed information:

p := organization.NewPerson("John", "Doe")
err := p.SetTwitterHandler("@jdoe")
if err != nil {
	fmt.Printf("An error occurred setting Twitter handler: %s\n", err.Error())
}

fmt.Println(p.ID()) // 12345
fmt.Println(p.FullName()) // John Doe
fmt.Println(p.TwitterHandler()) // @jdoe