2015-07-08 12 views
5

Tôi đang cố gắng viết một mẫu (sử dụng html/template) và truyền cho nó một cấu trúc có một số phương thức được đính kèm, nhiều phương thức trả về nhiều giá trị. Có cách nào để truy cập chúng từ bên trong khuôn mẫu không? Tôi muốn có thể làm điều gì đó như:Sử dụng các phương thức có nhiều giá trị trả về

package main 

import (
     "fmt" 
     "os" 
     "text/template" 
) 

type Foo struct { 
    Name string 
} 

func (f Foo) Baz() (int, int) { 
    return 1, 5 
} 

const tmpl = `Name: {{.Name}}, Ints: {{$a, $b := .Baz}}{{$a}}, {{b}}` 

func main() { 

    f := Foo{"Foo"} 

    t, err := template.New("test").Parse(tmpl) 
    if err != nil { 
     fmt.Println(err) 
    } 

    t.Execute(os.Stdout, f) 

} 

Nhưng rõ ràng điều này không hiệu quả. Không có cách nào xung quanh nó?

tôi đã xem xét việc tạo ra một cấu trúc vô danh trong mã của tôi:

data := struct { 
    Foo 
    a int 
    b int 
}{ 
    f, 
    0, 
    0, 
} 
data.a, data.b = f.Baz() 

Và qua đó, nhưng rất muốn có một cái gì đó trong mẫu. Ý tưởng nào? Tôi cũng đã thử viết một hàm wrapper mà tôi đã thêm vào funcMaps nhưng không bao giờ có thể làm việc đó cả.

Cảm ơn mọi đề xuất!

+0

không thể gọi chức năng từ mẫu, đó là sự thật. bạn sẽ tiếp tục với 'hàm wrapper'? hiển thị các tác phẩm hiện tại của bạn trên đó và cho phép mọi người giúp bạn làm việc đó. –

+0

Liên quan: [Văn bản/mẫu: “không thể gọi phương thức/chức năng với 0 kết quả.”] (Http://stackoverflow.com/questions/31221849/text-template-cant-call-method-function-with-0 -các kết quả). Giải pháp là như nhau: bạn phải tạo một hàm tùy chỉnh. – icza

+0

Tôi đã cố gắng để thực hiện một chức năng (FirstValue) mà sẽ có một chức năng như là đối số của nó, và sau đó trở về chỉ là giá trị đầu tiên của đầu ra ban đầu. Thật không may có vẻ như tôi không thể vượt qua phương pháp thông qua trong mẫu để nó sẽ không hoạt động: {{FirstValue .Baz}} gọi .Baz()}} thay vì vượt qua nó, vì vậy nó không phải là đi. –

Trả lời

5

Bạn sẽ không thể gọi hàm trả về hai giá trị trong mẫu trừ khi một trong các giá trị đó là lỗi. Điều này là để mẫu của bạn được đảm bảo hoạt động trong thời gian chạy. Có một câu trả lời tuyệt vời giải thích rằng here, nếu bạn quan tâm.

Để giải quyết vấn đề của bạn, bạn cần phải 1) chia chức năng của bạn thành hai hàm getter riêng biệt mà bạn có thể gọi ở vị trí phù hợp trong mẫu của bạn; hoặc 2) có hàm của bạn trả về một cấu trúc đơn giản với các giá trị bên trong.

Tôi không thể biết điều nào sẽ tốt hơn cho bạn bởi vì tôi thực sự không biết bạn cần triển khai gì. Foo và Baz không đưa ra nhiều manh mối. ;)

Dưới đây là một ví dụ nhanh-n-bẩn của tùy chọn một:

type Foo struct { 
    Name string 
} 

func (f Foo) GetA() (int) { 
    return 1 
} 

func (f Foo) GetB() (int) { 
    return 5 
} 

Và sau đó sửa đổi các mẫu phù hợp:

const tmpl = `Name: {{.Name}}, Ints: {{.GetA}}, {{.GetB}}` 

Hy vọng đây là một số giúp đỡ. :)

+0

Cảm ơn rất nhiều. Tôi có lẽ đó là trường hợp. Giải pháp của tôi liên quan đến việc thực hiện một bộ tính toán bằng cách lặp qua một tập hợp các mục và làm một số (liên kết) làm việc với chúng.Tôi đang cố gắng tránh chi phí lặp lại qua nhiều lần, về cơ bản sẽ tăng gấp đôi các tính toán cần thiết. Tôi thích ý tưởng đi qua một cấu trúc trở lại mặc dù, mà làm cho rất nhiều ý nghĩa. Cảm ơn! –

1

Cũng có khả năng trả về cấu trúc với nhiều trường và sử dụng chúng.

type Result struct { 
    First string 
    Second string 
} 

func GetResult() Result { 
    return Result{First: "first", Second: "second"} 
} 

Và sau đó sử dụng trong mẫu

{{$result := GetResult}} 
{{$result.First}} - {{$result.Second}} 
Các vấn đề liên quan