Interfaces + TODO/Questions!!!
This commit is contained in:
parent
51faf9b2c1
commit
834dbb82c4
1 changed files with 216 additions and 0 deletions
216
3methods/interfaces.go
Normal file
216
3methods/interfaces.go
Normal file
|
@ -0,0 +1,216 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
type Abser interface {
|
||||
Abs() float64
|
||||
}
|
||||
|
||||
type I interface {
|
||||
M()
|
||||
}
|
||||
|
||||
type I2 interface {
|
||||
C()
|
||||
}
|
||||
|
||||
type Vertex struct {
|
||||
X, Y float64
|
||||
}
|
||||
|
||||
type Vertex2 struct {
|
||||
X, Y float64
|
||||
}
|
||||
|
||||
type T struct {
|
||||
S string
|
||||
}
|
||||
|
||||
type MyFloat float64
|
||||
|
||||
func main() {
|
||||
fmt.Println("An interface type is defined as a set of method signatures")
|
||||
|
||||
var f Abser = MyFloat(1.2)
|
||||
var va Abser = &Vertex{3, 4}
|
||||
var v Abser = Vertex2{3, 4}
|
||||
// var v Abser = Vertex{3, 4} // ERROR, Same Vertex type not work because interface recognize them as same type
|
||||
|
||||
fmt.Println(f.Abs()) // goes to `func (f MyFloat) Abs() float64 {`
|
||||
fmt.Println(va.Abs()) // goes to `func (v *Vertex) Abs() float64 {`
|
||||
fmt.Println(v.Abs()) // goes to `func (v Vertex2) Abs() float64 {`
|
||||
|
||||
fmt.Println(reflect.TypeOf(f), reflect.TypeOf(f).Kind())
|
||||
fmt.Println(reflect.TypeOf(va), reflect.TypeOf(va).Kind())
|
||||
fmt.Println(reflect.TypeOf(v), reflect.TypeOf(v).Kind())
|
||||
|
||||
/*
|
||||
TODO No need to interfaces ?
|
||||
```
|
||||
f := MyFloat(1.2)
|
||||
va := &Vertex{3, 4}
|
||||
v := Vertex2{3, 4}
|
||||
```
|
||||
Also this code block works even with Abser interface removed ?
|
||||
|
||||
---
|
||||
|
||||
Also in this example: https://github.com/Furkan-Gulsen/turkce-go-egitimi#interfaces
|
||||
|
||||
There is no need to interfaces, just remove the interface and use methods normally as circle.area(), square.area() ...
|
||||
|
||||
What is our motivation to use Interfaces ???
|
||||
*/
|
||||
|
||||
// TODO what's the point! https://go.dev/tour/methods/10
|
||||
|
||||
// TODO In this example describe function uses Interface as argument. And this prevents multiple describe function. Is it a use case for interfacse (https://go.dev/tour/methods/11)
|
||||
|
||||
// TODO LOOK FOR HEAD-FIRST-GO EXAMPLES
|
||||
// LINK https://www.digitalocean.com/community/tutorials/how-to-use-interfaces-in-go
|
||||
// LINK https://duncanleung.com/understand-go-golang-interfaces/
|
||||
// LINK https://research.swtch.com/interfaces
|
||||
// TODO Understand interfaces more !
|
||||
|
||||
fmt.Printf("\n\n")
|
||||
fmt.Println("If the concrete value inside the interface itself is nil, the method will be called with a nil receiver")
|
||||
var i I
|
||||
var t *T
|
||||
|
||||
i = t
|
||||
describe(i)
|
||||
i.M()
|
||||
|
||||
i = &T{"hello"}
|
||||
describe(i)
|
||||
i.M()
|
||||
|
||||
fmt.Printf("\n")
|
||||
fmt.Println("A nil interface value holds neither value nor concrete type")
|
||||
|
||||
var i2 I2
|
||||
describe2(i2)
|
||||
// i2.C() // panic: runtime error: invalid memory address or nil pointer dereference
|
||||
|
||||
fmt.Printf("\n\n")
|
||||
fmt.Println("The interface type that specifies zero methods is known as the empty interface:")
|
||||
var i3 interface{}
|
||||
describe3(i3)
|
||||
fmt.Println("An empty interface may hold values of any type")
|
||||
|
||||
i3 = 43
|
||||
describe3(i3)
|
||||
|
||||
i3 = "hello"
|
||||
describe3(i3)
|
||||
|
||||
fmt.Println("Empty interfaces are used by code that handles values of unknown type")
|
||||
|
||||
fmt.Printf("\n\n")
|
||||
fmt.Println(" A type assertion provides access to an interface value's underlying concrete value. Can be used with t:=i.(T)")
|
||||
var i4 interface{} = "hello"
|
||||
|
||||
s := i4.(string)
|
||||
fmt.Println(s)
|
||||
|
||||
fmt.Println("You can also test if type is true with two variable. This also prevents panic")
|
||||
s, ok := i4.(string)
|
||||
fmt.Println(s, ok)
|
||||
|
||||
f2, ok := i4.(float64)
|
||||
fmt.Println(f2, ok) // 0 false
|
||||
|
||||
// f3 := i4.(float64) // panic: interface conversion: interface {} is string, not float64
|
||||
// fmt.Println(f3)
|
||||
|
||||
fmt.Println("\n\n")
|
||||
fmt.Println("You can also use interfaces for getting a variable as argument and then deciding type of this variable. var.(type) returns interfaces type. And then you can check different types with switch-case")
|
||||
somevar(61)
|
||||
somevar("hello")
|
||||
|
||||
fmt.Printf("\n\n")
|
||||
fmt.Println("One of the most ubiquitous interfaces is Stringer defined by the fmt package. A Stringer is a type that can describe itself as a string. he fmt package (and many others) look for this interface to print values.")
|
||||
|
||||
/*
|
||||
type Stringer interface {
|
||||
String() string
|
||||
}
|
||||
*/
|
||||
|
||||
fmt.Println("This means you can change output style with String() method for a type")
|
||||
myVarA := Person{"Aliberk Sandıkçı", 50}
|
||||
myVarB := Person{"Burak", 100}
|
||||
myVarC := Person2{"Kemal", 150}
|
||||
|
||||
fmt.Println(myVarA, myVarB, myVarC)
|
||||
|
||||
}
|
||||
|
||||
type Person struct {
|
||||
Name string
|
||||
Age int
|
||||
}
|
||||
|
||||
func (p Person) String() string {
|
||||
return fmt.Sprintf("%s + %d, ", p.Name, p.Age)
|
||||
}
|
||||
|
||||
type Person2 struct {
|
||||
Name string
|
||||
Age int
|
||||
}
|
||||
|
||||
func (p Person2) String() string {
|
||||
return fmt.Sprintf("%s ! %d", p.Name, p.Age)
|
||||
}
|
||||
|
||||
func somevar(i interface{}) {
|
||||
switch v := i.(type) {
|
||||
case int:
|
||||
fmt.Printf("INT: %v, %T\n", v, v)
|
||||
case string:
|
||||
fmt.Printf("STRING: %v, %T\n", v, v)
|
||||
default:
|
||||
fmt.Printf("OTHER: %v, %T\n", v, v)
|
||||
}
|
||||
// fmt.Println( i.(type) ) // Can't be used outside of switches!
|
||||
}
|
||||
|
||||
func (f MyFloat) Abs() float64 {
|
||||
if f < 0 {
|
||||
return float64(-f)
|
||||
}
|
||||
return float64(f)
|
||||
}
|
||||
|
||||
func (v *Vertex) Abs() float64 {
|
||||
return math.Sqrt(v.X*v.X + v.Y*v.Y)
|
||||
}
|
||||
|
||||
func (v Vertex2) Abs() float64 {
|
||||
return math.Sqrt(v.X*v.X+v.Y*v.Y) + 10
|
||||
}
|
||||
|
||||
func (t *T) M() {
|
||||
if t == nil {
|
||||
fmt.Println("<nil>")
|
||||
return
|
||||
}
|
||||
fmt.Println(t.S)
|
||||
}
|
||||
|
||||
func describe(i I) {
|
||||
fmt.Printf("(%v, %T)\n", i, i)
|
||||
}
|
||||
|
||||
func describe2(i I2) {
|
||||
fmt.Printf("(%v, %T)\n", i, i)
|
||||
}
|
||||
|
||||
func describe3(i interface{}) {
|
||||
fmt.Printf("(%v, %T)\n", i, i)
|
||||
}
|
Loading…
Reference in a new issue