当前位置: 首页 > 面试题库 >

模板不会将接口类型的字段评估为基础类型

袁泰平
2023-03-14
问题内容

使用golang
html/template(与的行为相同text/template)。如果我具有一个成员类型为接口类型的结构,则无法访问基础类型的成员(特别是尝试访问实现接口InnerInterface但通过InnerInterface接口类型而非结构类型返回的结构上的字段)


http://play.golang.org/p/ZH8wSK83oM

package main

import "fmt"
import "os"
import "html/template"

type InnerInterface interface{ InnerSomeMethod() }

type MyInnerStruct struct { Title string }
func (mis MyInnerStruct)InnerSomeMethod() { fmt.Println("Just to show we're satisfying the interface") }

type MyOuterStruct struct { Inner InnerInterface }


func main() {

    fmt.Println("Starting")


    arg := MyOuterStruct{Inner:MyInnerStruct{Title:"test1"}}

    err := template.Must(template.New("testtmpl").Parse("{{.Inner.Title}}")).Execute(os.Stdout, arg)
    if err != nil { panic(err) }

}

更改:更改type MyOuterStruct struct { Inner InnerInterface }为完全通用的接口,即使type MyOuterStruct struct { Inner interface{} }其正确呈现。这使我相信interface{}渲染引擎对它进行了特殊处理。

有什么比interface{}我每时每刻想要能够动态评估字段的方法更好的方法呢?


问题答案:

您的说法是正确的,interface{}渲染引擎对此进行了不同的处理。仅interface{}解包了值,没有解包了设置方法的接口值。我想这背后的原因是,如果您有接口类型,则可以将类型专门限制为方法集。因此,您不希望模板引擎尝试访问该接口后面的成员。

“问题”是由功能引起indirectexec.go

func indirect(v reflect.Value) (rv reflect.Value, isNil bool) {
    for ; v.Kind() == reflect.Ptr || v.Kind() == reflect.Interface; v = v.Elem() {
        if v.IsNil() {
            return v, true
        }
        if v.Kind() == reflect.Interface && v.NumMethod() > 0 {
            break
        }
    }
    return v, false
}

调用此方法以获得反射值的最深值。假设您在一个指针上有一个指针,则该函数将返回其中的最后一个。接口值也是如此。问题的关键是,只要接口值具有多个0方法,则间接寻址将在此处停止。正是您所描述的行为。

因为这似乎是预期的行为,所以您可以做的是Title() string 在接口中定义一个方法,并让它返回字符串。



 类似资料:
  • 模型在训练集上的误差通常称为 “训练误差” 或 “经验误差”,而在新样本上的误差称为 “泛化误差”。显然,机器学习的目的是得到泛化误差小的学习器。然而,在实际应用中,新样本是未知的,所以只能使训练误差尽量小。 当模型在训练集上表现很好而在新样本上误差很大时,称为 “过拟合”;反之,模型在训练集上误差就很大时,称为 “欠拟合”。 欠拟合通常容易解决,如 增加数据、增大训练次数、增大学习率或使用更复杂

  • 为了让程序有价值,我们需要能够处理最简单的数据单元:数字,字符串,结构体,布尔值等。 TypeScript支持与JavaScript几乎相同的数据类型,此外还提供了实用的枚举类型方便我们使用。 最基本的数据类型就是简单的true/false值,在JavaScript和TypeScript里叫做boolean(其它语言中也一样)。 let isDone: boolean = false; 和Java

  • 新建我们的person.ts,我们通过这一个文件,使用所有的基础类型。 实验 实验一 代码 enum Choose { Wife = 1, Mother = 2} // 选择 妻子 还是 妈妈 function question(choose: Choose) : void{ console.log('你老婆和你妈妈同时掉进水里你先救哪个?'); console.log('你的选

  • 字段选项 以下参数适用于所有字段类型。全部都是可选的。 null 如果是 True,Django 将允许在数据库该字段的值为 NULL。默认是 False。 blank 如果是 True,该字段被允许为空值。默认是 False。 !> 请注意,这不同于 null。null 纯粹是与数据库相关的,而 blank 与验证相关。如果一个字段有 blank=True,表单验证将允许输入一个空值。如果一个字

  • 在上一节中,字段的配置是这样的。S则是引入的Sequelize,为了编写方便,重命名了一下。 { email: S.STRING, name: S.STRING } 在 define 函数的声明里面,需要传入的字段配置项其实是 DefineAttributes 类型。 [name: string]: string | DataTypeAbstract | DefineAttribu

  • 问题内容: 有什么方法可以使用反射设置界面字段?当我尝试设置它时,它惊慌地说该值不可寻址。 问题答案: 接口没有字段,它们仅定义包含的值的方法集。在界面上进行反射时,可以使用提取值。 您也不能取消导出字段。您需要大写您的类型的字段名称。遍历字段时,用于测试它们是否可设置。如果该值不可寻址或该值仍在接口中,则也会返回false。 您的代码的有效示例:http : //play.golang.org/