草庐IT

go - 混合 := and = in Go if statements

coder 2023-06-28 原文

Go 有一个常见的习语,看起来像这样:

if val, err := func(); err != nil {
    /* val and err are in scope */
...
}
/* val and err are no longer in scope */

使用“短赋值”。我当然是粉丝。感觉类似于:

/* code not involving val */
{
    int val;

    if ((val = func()) == ERR_VALUE) {
        /* Process the error */
    }
    /* Do something with val */
}
/* more code not involving val */

在 C++ 中。让我感到困惑的是,如果 if 的第一个子句中有多个变量,它们必须具有相同的范围,即您必须执行以下任一操作:

var err error
var val string

if val, err = func(); err != nil {
...

if val, err := func(); err != nil {
...

一个非常常见的用例似乎是您有一个要在 if 的第一个子句中设置的变量,测试错误,如果没有错误,则继续程序的其余部分流(并且能够使用您在执行 if 时分配的任何值)。但是,在我看来,如果你想这样做,你必须:

  1. 使用临时变量,然后在 else 中分配持久变量值:

    var val
    
    if tempval, err := func(); err != nil {
        /* Process the error */
    } else {
        val = tempval
    }
    
  2. 如上所述,声明范围超出 if 的 err 变量。

第一个选项看起来很笨拙——被迫使用“else”子句只是为了确保该值不会超出范围——第二个选项放弃了限制变量范围的优势。对于这种(看似很常见的)情况,更有经验的 Go 程序员会使用哪些惯用语?

最佳答案

The Go Programming Language Specification

If statements

"If" statements specify the conditional execution of two branches according to the value of a boolean expression. If the expression evaluates to true, the "if" branch is executed, otherwise, if present, the "else" branch is executed.

IfStmt = "if" [ SimpleStmt ";" ] Expression Block [ "else" ( IfStmt | Block ) ] .

.

if x > max {
  x = max
}

The expression may be preceded by a simple statement, which executes before the expression is evaluated.

if x := f(); x < y {
  return x
} else if x > z {
  return z
} else {
  return y
}

如果不能利用特殊形式,

if val, err := fnc(); err != nil {
    // ...
}

然后使用常规形式,

val, err := fnc()
if err != nil {
    // ... 
}

正则形式是Go语言必备的常用形式。为方便起见,特殊形式是常规形式的特化;这不是必需的。如果特殊形式比常规形式更方便使用,就使用它。否则,使用常规形式。


Go 是一个 block-structured programming language追溯到 Algol 60、C、Pascal、Modula 2 和 Oberon。

The Go Programming Language Specification

Blocks

Declarations and scope

因此,你可以这样写

x := false
{
    x := true
    if x {
        fmt.Println(x)
    }
}
fmt.Println(x)

或者,等价地,为了方便,

x := false
if x := true; x {
    fmt.Println(x)
}
fmt.Println(x)

两种情况下的输出都是

true
false

关于go - 混合 := and = in Go if statements,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35213208/

有关go - 混合 := and = in Go if statements的更多相关文章

  1. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  2. ruby-on-rails - rails : save file from URL and save it to Amazon S3 - 2

    从给定URL下载文件并立即将其上传到AmazonS3的更直接的方法是什么(+将有关文件的一些信息保存到数据库中,例如名称、大小等)?现在,我既不使用Paperclip,也不使用Carrierwave。谢谢 最佳答案 简单明了:require'open-uri'require's3'amazon=S3::Service.new(access_key_id:'KEY',secret_access_key:'KEY')bucket=amazon.buckets.find('image_storage')url='http://www.ex

  3. ruby - Chef : Read variable from file and use it in one converge - 2

    我有以下代码,它下载一个文件,然后将文件的内容读入一个变量。使用该变量,它执行一个命令。这个配方不会收敛,因为/root/foo在编译阶段不存在。我可以通过多个聚合和一个来解决这个问题ifFile.exist但我想用一个收敛来完成它。关于如何做到这一点有什么想法吗?execute'download_joiner'docommand"awss3cps3://bucket/foo/root/foo"not_if{::File.exist?('/root/foo')}endpassword=::File.read('/root/foo').chompexecute'join_domain'd

  4. ruby-on-rails - rspec 测试 has_many :through and after_save - 2

    我有一个(我认为)相对简单的has_many:through与连接表的关系:classUser:user_following_thing_relationshipsendclassThing:user_following_thing_relationships,:source=>:userendclassUserFollowingThingRelationship还有这些rspec测试(我知道这些不一定是好的测试,这些只是为了说明正在发生的事情):describeThingdobefore(:each)do@user=User.create!(:name=>"Fred")@thing=

  5. ruby - 如何测试正在使用 RSpec 和 Mocha 调用的混合类方法? - 2

    我有一个模块:moduleMyModuledefdo_something#...endend由类使用如下:classMyCommandextendMyModuledefself.execute#...do_somethingendend如何验证MyCommand.execute调用了do_something?我已经尝试使用mocha进行部分模拟,但是当未调用do_something时它不会失败:it"callsdo_something"doMyCommand.stubs(:do_something)MyCommand.executeend 最佳答案

  6. ruby-on-rails - 为什么 DataMapper 使用混合与继承? - 2

    所以我只是对此感到好奇:DataMapper为其模型使用混合classPostincludeDataMapper::Resource虽然active-record使用继承classPost有谁知道为什么DataMapper选择这样做(或者为什么AR选择不这样做)? 最佳答案 它允许您从另一个不是DM类的类继承。它还允许动态地将DM功能添加到类中。这是我正在处理的模块中的类方法:defdatamapper_classklass=self.dupklass.send(:include,DataMapper::Resource)klass

  7. ruby - :variable and @variable 之间的差异 - 2

    作为RubyonRails新手,我明白“@”和“:”引用有不同的含义。我看到了thispost在SO中,其中描述了一些差异。@表示实例变量(例如@my_selection):表示别名(例如:my_selection)我遇到了一个情况,我有一个标准的MVC页面,类似于我的网络应用程序中的所有其他表单/页面。html.erb片段route.rb片段resources:my_selections当我尝试访问此页面时,出现此错误:NoMethodErrorinselections#createShowingC:/somedir/myapp/app/views/my_selections/ind

  8. ruby-on-rails - Assets 管道损坏 : Not compiling on the fly css and js files - 2

    我开始了一个新的Rails3.2.5项目,Assets管道不再工作了。CSS和Javascript文件不再编译。这是尝试生成Assets时日志的输出:StartedGET"/assets/application.css?body=1"for127.0.0.1at2012-06-1623:59:11-0700Servedasset/application.css-200OK(0ms)[2012-06-1623:59:11]ERRORNoMethodError:undefinedmethod`each'fornil:NilClass/Users/greg/.rbenv/versions/1

  9. ruby-on-rails - 将 Ruby 代码和文字标记与 Haml 混合 - 2

    如何用HAML编写这个ERB:#OR我可以:=some_ruby_code+":"#and=some_ruby_code%br但我不想在这里连接,我想将它写成内联:(=some_ruby_code):#and(=some_ruby_code)%br 最佳答案 =some_ruby_code+":"-#and=some_ruby_code+""编辑1:我不确定您在寻找什么。你想要其中之一吗?==#{some_ruby_code}:-#and==#{some_ruby_code}或==#{some_ruby_code}:-#and=so

  10. ruby-on-rails - Textmate 'Go to symbol' 相当于 Vim - 2

    在Railcasts上,我注意到一个非常有趣的功能“转到符号”窗口。它像Command-T一样工作,但显示当前文件中可用的类和方法。如何在vim中获取它? 最佳答案 尝试:helptags有各种程序和脚本可以生成标记文件。此外,标记文件格式非常简单,因此很容易将sed(1)或类似的脚本组合在一起,无论您使用何种语言,它们都可以生成标记文件。轻松获取标记文件(除了下载生成器之外)的关键在于格式化样式而不是实际解析语法。 关于ruby-on-rails-Textmate'Gotosymbol

随机推荐