草庐IT

go - 来自嵌入式类型的复合文字和字段

coder 2024-07-11 原文

我正在编写一个示例程序来回答这里关于 SO 的另一个问题,发现自己对以下代码无法编译这一事实感到有些困惑;

https://play.golang.org/p/wxBGcgfs1o

package main

import "fmt"

type A struct {
    FName string
    LName string
}

type B struct {
    A
}

func (a *A) Print() {
     fmt.Println(a.GetName())
}

func (a *A) GetName() string {
     return a.FName
}

func (b *B) GetName() string {
     return b.LName
}

func main() {
    a := &A{FName:"evan", LName:"mcdonnal"}
    b := &B{FName:"evan", LName:"mcdonnal"}

    a.Print()
    b.Print()
}

错误是;

/tmp/sandbox596198095/main.go:28: unknown B field 'FName' in struct literal
/tmp/sandbox596198095/main.go:28: unknown B field 'LName' in struct literal

是否可以在静态初始化器中设置嵌入类型的字段值?如何?对我来说,这似乎是一个编译器错误;如果我面前没有资源并且熟悉类型,我会用头撞墙说“显然 FName 存在于 B 上,编译器在说什么!?!?!”。

为了抢占典型答案,我知道最接近的工作语法是 b := &B{A{FName:"evan", LName:"mcdonnal"}} 但该语法是在我看来,嵌入在概念上是矛盾的,所以如果它是唯一的选择,我会感到失望。如果这是唯一的方法,它是 Go 编译器的缺点,还是实际上存在一个理论上的限制,会阻止编译器解释我的非工作示例中的语法?

最佳答案

这不是编译器错误,而是设计决策。语言规范只是指出:

Promoted fields act like ordinary fields of a struct except that they cannot be used as field names in composite literals of the struct.

我想这背后的原因是为了避免歧义。使用选择器时有一些规则可以解决名称冲突,并且它们必须很复杂才能允许您的建议。最重要的是,如果您在嵌入类型的结构文字中使用嵌入结构的现有实例,则可能会产生歧义。

编辑:这是一个示例,其中这种方法可能会适得其反:

考虑这样一种情况,您有 A 嵌入 B,以及您想要嵌入的 A 实例:

type A {
   X int
}

type B {
   A
}

做起来很简单

b := B{ X: 1 } 

并推断应该做什么。 但是,如果我们已经有了 A 的实例怎么办?这没有意义:

a := A { X: 1 }

b := B { X: 2, A: a, } 

您是否首先将 2 分配给 A 的零实例,然后在其上分配 A 的初始化实例?它是否等同于:

b := B { A: a, X: 2 }  ?

它打破了初始化顺序与字段名称的复合文字无关的假设。

关于go - 来自嵌入式类型的复合文字和字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29979056/

有关go - 来自嵌入式类型的复合文字和字段的更多相关文章

  1. ruby - 如何使用文字标量样式在 YAML 中转储字符串? - 2

    我有一大串格式化数据(例如JSON),我想使用Psychinruby​​同时保留格式转储到YAML。基本上,我希望JSON使用literalstyle出现在YAML中:---json:|{"page":1,"results":["item","another"],"total_pages":0}但是,当我使用YAML.dump时,它不使用文字样式。我得到这样的东西:---json:!"{\n\"page\":1,\n\"results\":[\n\"item\",\"another\"\n],\n\"total_pages\":0\n}\n"我如何告诉Psych以想要的样式转储标量?解

  2. ruby-on-rails - 如何验证非模型(甚至非对象)字段 - 2

    我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss

  3. ruby-on-rails - form_for 中不在模型中的自定义字段 - 2

    我想向我的Controller传递一个参数,它是一个简单的复选框,但我不知道如何在模型的form_for中引入它,这是我的观点:{:id=>'go_finance'}do|f|%>Transferirde:para:Entrada:"input",:placeholder=>"Quantofoiganho?"%>Saída:"output",:placeholder=>"Quantofoigasto?"%>Nota:我想做一个额外的复选框,但我该怎么做,模型中没有一个对象,而是一个要检查的对象,以便在Controller中创建一个ifelse,如果没有检查,请帮助我,非常感谢,谢谢

  4. ruby - Infinity 和 NaN 的类型是什么? - 2

    我可以得到Infinity和NaNn=9.0/0#=>Infinityn.class#=>Floatm=0/0.0#=>NaNm.class#=>Float但是当我想直接访问Infinity或NaN时:Infinity#=>uninitializedconstantInfinity(NameError)NaN#=>uninitializedconstantNaN(NameError)什么是Infinity和NaN?它们是对象、关键字还是其他东西? 最佳答案 您看到打印为Infinity和NaN的只是Float类的两个特殊实例的字符串

  5. ruby - 检查方法参数的类型 - 2

    我不确定传递给方法的对象的类型是否正确。我可能会将一个字符串传递给一个只能处理整数的函数。某种运行时保证怎么样?我看不到比以下更好的选择:defsomeFixNumMangler(input)raise"wrongtype:integerrequired"unlessinput.class==FixNumother_stuffend有更好的选择吗? 最佳答案 使用Kernel#Integer在使用之前转换输入的方法。当无法以任何合理的方式将输入转换为整数时,它将引发ArgumentError。defmy_method(number)

  6. ruby-on-rails - 在 Rails 和 ActiveRecord 中查询时忽略某些字段 - 2

    我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr

  7. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  8. ruby - 查找字符串中的内容类型(数字、日期、时间、字符串等) - 2

    我正在尝试解析一个CSV文件并使用SQL命令自动为其创建一个表。CSV中的第一行给出了列标题。但我需要推断每个列的类型。Ruby中是否有任何函数可以找到每个字段中内容的类型。例如,CSV行:"12012","Test","1233.22","12:21:22","10/10/2009"应该产生像这样的类型['integer','string','float','time','date']谢谢! 最佳答案 require'time'defto_something(str)if(num=Integer(str)rescueFloat(s

  9. ruby-on-rails - 在 Rails 开发环境中为 .ogv 文件设置 Mime 类型 - 2

    我正在玩HTML5视频并且在ERB中有以下片段:mp4视频从在我的开发环境中运行的服务器很好地流式传输到chrome。然而firefox显示带有海报图像的视频播放器,但带有一个大X。问题似乎是mongrel不确定ogv扩展的mime类型,并且只返回text/plain,如curl所示:$curl-Ihttp://0.0.0.0:3000/pr6.ogvHTTP/1.1200OKConnection:closeDate:Mon,19Apr201012:33:50GMTLast-Modified:Sun,18Apr201012:46:07GMTContent-Type:text/plain

  10. ruby - 字符串文字中的转义状态作为 `String#tr` 的参数 - 2

    对于作为String#tr参数的单引号字符串文字中反斜杠的转义状态,我觉得有些神秘。你能解释一下下面三个例子之间的对比吗?我特别不明白第二个。为了避免复杂化,我在这里使用了'd',在双引号中转义时不会改变含义("\d"="d")。'\\'.tr('\\','x')#=>"x"'\\'.tr('\\d','x')#=>"\\"'\\'.tr('\\\d','x')#=>"x" 最佳答案 在tr中转义tr的第一个参数非常类似于正则表达式中的括号字符分组。您可以在表达式的开头使用^来否定匹配(替换任何不匹配的内容)并使用例如a-f来匹配一

随机推荐