You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift中Self的困惑:结构体内外同名变量的访问问题

Swift结构体内部访问外部同名变量的问题

代码片段

var _message = "Outside Message"

struct MyStruct {
  var _message  = "Inside Message"
  var message: String {
    mutating get {
      print(_message)
      print(self._message)

      _message = "New Message for Outside"
      self._message = "New Message for Inside"

      return self._message
    }
  }
}

var aStruct = MyStruct()
print("Result: \(aStruct.message)")

运行输出

Inside Message
Inside Message
Result: New Message for Inside

疑问

为什么在MyStruct内部,使用self与否都只会引用内部的_message变量?如何在message属性中引用外部的_message变量?


解答

1. 为什么_message和self._message都指向内部变量

这是Swift的**作用域遮蔽(Shadowing)**规则导致的:当局部作用域(这里是结构体实例的成员作用域)存在和外部作用域(全局作用域)同名的变量时,局部变量会优先被访问。

self在结构体内部代表当前的实例对象,self._message明确指向实例的成员变量;而直接写_message时,编译器会优先在当前作用域(结构体实例的成员作用域)查找变量,自然也会匹配到内部的_message,所以两者指向的都是同一个内部变量。

2. 如何引用外部的_message

要访问被遮蔽的全局_message,你需要明确指定它的作用域,有两种常用方式:

方式一:通过模块名限定

全局变量默认属于当前模块,在Playground中模块名就是你的Playground文件名(比如你的Playground叫MyPlayground),直接用模块名+变量名即可访问:

mutating get {
  // 访问全局的_message
  print(MyPlayground._message)
  // 访问内部的_message
  print(self._message)

  MyPlayground._message = "New Message for Outside"
  self._message = "New Message for Inside"

  return self._message
}
方式二:封装全局变量到命名空间

把全局变量放到一个自定义的命名空间结构体中,通过静态属性访问,这样更清晰,也不依赖模块名:

// 封装全局变量到命名空间
struct Global {
  static var _message = "Outside Message"
}

struct MyStruct {
  var _message  = "Inside Message"
  var message: String {
    mutating get {
      print(Global._message)
      print(self._message)

      Global._message = "New Message for Outside"
      self._message = "New Message for Inside"

      return self._message
    }
  }
}

内容的提问来源于stack exchange,提问作者Moshe W

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 10:12:52