如何在下面干?

时间:2017-04-17 19:05:53

标签: go

添加了getName()功能的典型示例。

我想知道我怎么能不为getName()circle两次写rect

package main

import "fmt"
import "math"

// Here's a basic interface for geometric shapes.
type geometry interface {
    area() float64
    perim() float64
    getName() string
}

// For our example we'll implement this interface on
// `rect` and `circle` types.
type rect struct {
    width, height float64
    name string
}
type circle struct {
    radius float64
    name string
}

// To implement an interface in Go, we just need to
// implement all the methods in the interface. Here we
// implement `geometry` on `rect`s.
func (r rect) area() float64 {
    return r.width * r.height
}
func (r rect) perim() float64 {
    return 2*r.width + 2*r.height
}
func (r rect) getName() string {
    return r.name
}

// The implementation for `circle`s.
func (c circle) area() float64 {
    return math.Pi * c.radius * c.radius
}
func (c circle) perim() float64 {
    return 2 * math.Pi * c.radius
}
func (c circle) getName() string {
    return c.name
}

// If a variable has an interface type, then we can call
// methods that are in the named interface. Here's a
// generic `measure` function taking advantage of this
// to work on any `geometry`.
func measure(g geometry) {
    fmt.Println(g)
    fmt.Println(g.area())
    fmt.Println(g.perim())
    fmt.Println(g.getName())
}

func main() {
    r := rect{width: 3, height: 4, name: "rect5"}
    c := circle{radius: 5, name: "circle2"}

    // The `circle` and `rect` struct types both
    // implement the `geometry` interface so we can use
    // instances of
    // these structs as arguments to `measure`.
    measure(r)
    measure(c)
}

2 个答案:

答案 0 :(得分:1)

您可以 - 并且可能应该 - 将您的几何类型嵌入到包含该名称的另一个结构类型中。除非名称是“圆圈”或“方形”或者您有什么,否则名称实际上与几何本身无关。所以你可以:

@login_required
def datosPersonales(request):
    query = informacionFacturacion.objects.filter(usuario=request.user)

    if request.method == "POST":  # This will handle the template form's POST
        form = informacionFacturacionForm(request.POST)
        if form.is_valid():
            asd = form.save(commit=False)
            asd.save()
            # Here you may want to redirect to somewhere else
    # Im not sure here, I guess that you want to handle the GET method if 
    # there is no form in the request. Post your template form to see what
    # is happening.
    else:
        form = informacionFacturacionForm(instance=query)
        # you dont need to save it, it is already in DB

    context = {
        "titulo": "Datos personales | Co.",
        "body_class": "class= sidebar_main_open sidebar_main_swipe",
        # I think here is your main issue, you are handling a form object
        # AND a infoFacturacion object. You need to use just the
        # form object in the template and render it accordingly.
        "form": form,   
        "infoFacturacion": query, 
    }
    template = "micuenta/datosPersonales.html"
    return render(request, template, context)

这将起到同样的作用,保持干燥,并保持关注点的分离。嵌入type namedGeometry struct { geometry name string } func (ng *namedGeometry) getName() string { return ng.name } 后,您仍然可以在geometry个实例上调用geometry方法。

答案 1 :(得分:0)

我会采用类似于Adrian的方法,但我会在其他类型中嵌入一个基本类型,它具有通用功能,例如。

type baseShape struct {
    name string
}

func (s *baseShape) getName() string {
    return s.name
}

type rect struct {
    width, height float64
    baseShape
}

type circle struct {
    radius float64
    baseShape
}

执行此操作后,您只需要在每种类型的基础上实现形状不同的功能。