2017-08-13 54 views
0

我使用本地sql庫和jmoiron/sqlx從postgres數據庫填充結構列表。我現在有用於不同類型的獨立的功能,例如:製作底層類型的接口{}參數的副本

func selectAccounts(ext sqlx.Ext, query string, args []interface{}) ([]Account, error) { 
    var accts []Account 
    rows, err := ext.Queryx(query, args...) 
    if err != nil { 
     return nil, err 
    } 
    defer rows.Close() 

    for rows.Next() { 
     var a Account 
     if err = rows.StructScan(&a); err != nil { 
      return nil, err 
     } 
     accts = append(accts, a) 
    } 
    err = rows.Err() 
    return accts, err 
} 

...但我必須建立一個接受接口{},並返回一個[]接口{}的通用功能的一個要求。我發現替換上述行var a Account的過程很困難,因爲它需要複製傳入的接口{}類型,同時複製其基礎類型。我是否應該向自己反映,我需要使用反思,還是有另一種方式去做這件事?

+0

您需要反射才能實現通用功能。 – jeevatkm

+0

爲什麼要接受'interface {}'類型,然後返回'[] interface {}'?不要在函數中創建'[] Account',只需創建一個'[] interface {}','append'並返回它。 –

回答

0

難道你不能讓你的結構多態,並讓他們實現一個單一的接口?那麼你的函數可以返回一片上述界面?這樣你就不必使用反射。我正沿着這些路線思考的東西:

package main 

import (
    "fmt" 
) 

type Account interface { 
    GetDetails() string 
} 

type PersonAccount struct { 
    Name string 
} 

func NewPersonAccount(name string) Account { 
    return &PersonAccount{ 
     Name: name, 
    } 
} 

func (account *PersonAccount) GetDetails() string { 
    return account.Name 
} 

type BillingAccount struct { 
    AccountNumber string 
} 

func NewBillingAccount(accountNumber string) Account { 
    return &BillingAccount{ 
     AccountNumber: accountNumber, 
    } 
} 

func (account *BillingAccount) GetDetails() string { 
    return account.AccountNumber 
} 

func getAllAccounts() []Account { 
    accounts := make([]Account, 0) 
    accounts = append(accounts, NewPersonAccount("John Doe")) 
    accounts = append(accounts, NewBillingAccount("1234-5678")) 

    return accounts 
} 

func main() { 
    accounts := getAllAccounts() 

    for _, account := range accounts { 
     fmt.Println(account.GetDetails()) 
    } 
} 

/* Output: 
John Doe 
1234-5678 
*/ 
0

首先,似乎是你在你的描述別說什麼截至目前

之間的差別,但我必須建立一個通用功能的要求,即接受 interface {}並返回一個[] interface {}。

以及您的代碼的作用(它接受一個接口的切片而不是接口)。

你可能不需要接受的接口片中在功能參數你的代碼目前確實,可以只接受一個接口,讓你的函數可以看起來像:

func selectAccounts(ext sqlx.Ext, query string, args interface{}) ([]Account, error) { 

您可以返回的切片界面,並有任何類型的內部。請看看這個https://play.golang.org/p/NcLxhsiqK8

由於@ ivan.sim提到,你可以在接口片上添加Account而不是創建片Accounts