string - 通过字符串文字与初始化程序的 Swift 字符串

标签 string swift string-literals

在其他语言(例如 Java)中,通过字符串文字获取的字符串与通过初始化程序获取的字符串实际上是有区别的。在 Swift 中,它们在底层是等价的吗?

例如

var string:String = ""
var string:String = String()

引用这个SO post有关 Java 中文字和对象之间差异的信息。

最佳答案

根据 Apple 文档,声明是等效的:

Initializing an Empty String

To create an empty String value as the starting point for building a longer string, either assign an empty string literal to a variable, or initialize a new String instance with initializer syntax:

var emptyString = ""               // empty string literal
var anotherEmptyString = String()  // initializer syntax
// these two strings are both empty, and are equivalent to each other

引用:https://developer.apple.com/library/prerelease/ios/documentation/Swift/Conceptual/Swift_Programming_Language/StringsAndCharacters.html

如果我们查看程序集,我们会发现这两个构造函数使用相同的指令。

字符串.swift:

let str = String()
let str2 = ""

编译后的程序集(swiftc -emit-assembly string.swift):

    .section    __TEXT,__text,regular,pure_instructions
    .macosx_version_min 14, 3
    .globl  _main
    .align  4, 0x90
_main:
    .cfi_startproc
    pushq   %rbp
Ltmp0:
    .cfi_def_cfa_offset 16
Ltmp1:
    .cfi_offset %rbp, -16
    movq    %rsp, %rbp
Ltmp2:
    .cfi_def_cfa_register %rbp
    subq    $16, %rsp
    movq    _globalinit_33_1BDF70FFC18749BAB495A73B459ED2F0_token4@GOTPCREL(%rip), %rax
    movq    _globalinit_33_1BDF70FFC18749BAB495A73B459ED2F0_func4@GOTPCREL(%rip), %rcx
    xorl    %edx, %edx
    movl    %edi, -4(%rbp)
    movq    %rax, %rdi
    movq    %rsi, -16(%rbp)
    movq    %rcx, %rsi
    callq   _swift_once
    movq    _globalinit_33_1BDF70FFC18749BAB495A73B459ED2F0_token5@GOTPCREL(%rip), %rdi
    movq    _globalinit_33_1BDF70FFC18749BAB495A73B459ED2F0_func5@GOTPCREL(%rip), %rax
    xorl    %r8d, %r8d
    movl    %r8d, %edx
    movq    __TZvOSs7Process5_argcVSs5Int32@GOTPCREL(%rip), %rcx
    movl    -4(%rbp), %r8d
    movl    %r8d, (%rcx)
    movq    %rax, %rsi
    callq   _swift_once
    movq    __TZvOSs7Process11_unsafeArgvGVSs20UnsafeMutablePointerGS0_VSs4Int8__@GOTPCREL(%rip), %rax
    movq    -16(%rbp), %rcx
    movq    %rcx, (%rax)
    callq   __TFSSCfMSSFT_SS
    leaq    L___unnamed_1(%rip), %rdi
    xorl    %r8d, %r8d
    movl    %r8d, %esi
    movl    $1, %r8d
    movq    %rax, __Tv6string3strSS(%rip)
    movq    %rdx, __Tv6string3strSS+8(%rip)
    movq    %rcx, __Tv6string3strSS+16(%rip)
    movl    %r8d, %edx
    callq   __TFSSCfMSSFT21_builtinStringLiteralBp8byteSizeBw7isASCIIBi1__SS
    xorl    %r8d, %r8d
    movq    %rax, __Tv6string4str2SS(%rip)
    movq    %rdx, __Tv6string4str2SS+8(%rip)
    movq    %rcx, __Tv6string4str2SS+16(%rip)
    movl    %r8d, %eax
    addq    $16, %rsp
    popq    %rbp
    retq
    .cfi_endproc

    .globl  __Tv6string3strSS
.zerofill __DATA,__common,__Tv6string3strSS,24,3
    .globl  __Tv6string4str2SS
.zerofill __DATA,__common,__Tv6string4str2SS,24,3
    .section    __TEXT,__cstring,cstring_literals
L___unnamed_1:
    .space  1

    .no_dead_strip  __Tv6string3strSS
    .no_dead_strip  __Tv6string4str2SS
    .linker_option "-lswiftCore"
    .section    __DATA,__objc_imageinfo,regular,no_dead_strip
L_OBJC_IMAGE_INFO:
    .long   0
    .long   512


.subsections_via_symbols

请注意 str 和 str2 的声明具有相同的说明:

xorl    %r8d, %r8d
movl    %r8d, %esi
movl    $1, %r8d
movq    %rax, __Tv6string3strSS(%rip)
movq    %rdx, __Tv6string3strSS+8(%rip)
movq    %rcx, __Tv6string3strSS+16(%rip)
movl    %r8d, %edx

# ...

xorl    %r8d, %r8d
movq    %rax, __Tv6string4str2SS(%rip)
movq    %rdx, __Tv6string4str2SS+8(%rip)
movq    %rcx, __Tv6string4str2SS+16(%rip)
movl    %r8d, %eax

您可以通过查看 Apple's documentation 了解有关字符串文字的更多信息.

关于string - 通过字符串文字与初始化程序的 Swift 字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31197008/

相关文章:

ruby - 如何检查 Ruby 数组是否包含多个值之一?

c++ - 从 C++ 字符串中删除注释

c++ - Intellisense 期望 ';' 带有多行字符串文字

编译器不允许我编辑传递的字符串

c++ - 错误 : cannot increment value of type 'char [6]'

PHP子串删除

php - implode() 字符串,但也在末尾附加胶水

ios - 如何链接两个相互连接的 Collection View ?

swift uitapgesturerecognizer 传递参数

swift - 当基类具有同名的可选属性时,协议(protocol)属性的重新声明无效