Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-cloud-platform/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
有没有一种干净的方法来指定Swift中的字符文字?_Swift_Character_Literals - Fatal编程技术网

有没有一种干净的方法来指定Swift中的字符文字?

有没有一种干净的方法来指定Swift中的字符文字?,swift,character,literals,Swift,Character,Literals,斯威夫特似乎试图驳斥字符串由原子字符数组组成的概念,这对于许多用途都是有意义的,但是有很多编程都涉及到挑选所有实际用途的ASCII数据结构:特别是对于文件I/O。缺少用于指定字符文字的内置语言功能似乎是一个巨大的漏洞,也就是说,没有类似C/Java/etc的功能: String foo="a" char bar='a' 这相当不方便,因为即使将字符串转换为字符数组,也无法执行以下操作: let ch:unichar = arrayOfCharacters[n] if ch >= 'a'

斯威夫特似乎试图驳斥字符串由原子字符数组组成的概念,这对于许多用途都是有意义的,但是有很多编程都涉及到挑选所有实际用途的ASCII数据结构:特别是对于文件I/O。缺少用于指定字符文字的内置语言功能似乎是一个巨大的漏洞,也就是说,没有类似C/Java/etc的功能:

String foo="a"
char bar='a'
这相当不方便,因为即使将字符串转换为字符数组,也无法执行以下操作:

let ch:unichar = arrayOfCharacters[n]
if ch >= 'a' && ch <= 'z' {...whatever...}
让ch:unichar=arrayOfCharacters[n]

如果ch>='a'&&ch=LOWCASE\u a&&ch
字符
可以从
字符串
创建,只要那些
字符串
仅由单个字符组成。而且,由于
Character
实现了
extendedGraphimeClusterLiteralConvertible
,Swift将在分配时自动为您执行此操作。因此,要在Swift中创建
字符
,只需执行以下操作:

let ch: Character = "a"
然后,您可以使用
IntervalType
(使用生成)的
contains
方法检查字符是否在您要查找的范围内:

if ("a"..."z").contains(ch) {
    /* ... whatever ... */
}
例如:

let ch: Character = "m"
if ("a"..."z").contains(ch) {
    println("yep")
} else {
    println("nope")
}
产出:

是的


更新:正如@MartinR所指出的,Swift字符的顺序是基于而不是与ASCII字符代码相同的顺序。在您的特定情况下,
a
z
之间的字符比直接ASCII中的字符多(例如,
a
)。更多信息请参见@MartinR的答案

如果需要检查字符是否位于两个ASCII字符代码之间,则可能需要执行类似于原始解决方法的操作。但是,您还必须将
ch
转换为
unichar
而不是
字符才能工作(有关
Character
unichar
的更多信息,请参阅):

或者,不使用
NSString
的更详细的方式:

let startCharScalars = "a".unicodeScalars
let startCode = startCharScalars[startCharScalars.startIndex]

let endCharScalars = "z".unicodeScalars
let endCode = endCharScalars[endCharScalars.startIndex]

let chScalars = String(ch).unicodeScalars
let chCode = chScalars[chScalars.startIndex]

if (startCode...endCode).contains(chCode) {
    println("yep")
} else {
    println("nope")
}

注意:仅当字符仅包含一个代码点时,这两个示例才起作用,但只要我们仅限于ASCII,这应该不会有问题。

如果您需要C样式的ASCII文本,您可以执行以下操作:

let chr = UInt8(ascii:"A") // == UInt8( 0x41 )
或者,如果需要32位Unicode文本,可以执行以下操作:

let unichr1 = UnicodeScalar("A").value // == UInt32( 0x41 )
let unichr2 = UnicodeScalar("é").value // == UInt32( 0xe9 )
let unichr3 = UnicodeScalar("It also looks like you can use the following syntax:

Character("a")
让unichr1=UnicodeScalar(“A”)。值//==UInt32(0x41)
设unichr2=UnicodeScalar(“é”).value/==UInt32(0xe9)

让unichr3=UnicodeScalar(“看起来您还可以使用以下语法:

let foo = "abcDeé@¶œŎO!@#"

foo.forEach { c in
    print((c.isASCII ? "\(c) is ascii with value \(c.asciiValue ?? 0); " : "\(c) is not ascii; ")
        + ((c.isLetter ? "\(c) is a letter" : "\(c) is not a letter")))
}
这将从指定的单个字符串创建一个
字符

我只在Swift 4和Xcode 10.1中测试过这一点,您想要的功能是,但由于以下几个原因,该提案被拒绝:

  • 含糊不清 在当前的Swift生态系统中,所写的提案将允许使用类似于
    'x'+'y'==“xy”
    的表达式,而这并非本意(正确的语法将是
    “x”+“y”==“xy”

  • 合并 该提案是二合一的

    首先,它提出了一种在语言中引入单引号文字的方法

    其次,它建议将这些转换为数字类型,以处理ASCII值和Unicode码点

    这些都是很好的提案,建议将其分为两部分重新提出。这些后续提案尚未正式确定。

  • 分歧 它从未就
    'x'
    的默认类型是a还是a达成一致意见。尽管缺乏一致意见,该提案还是使用了
    字符
    ,引用了

  • 你可以阅读


    语法可能如下所示:

    let LOWCASE_A = ("a" as NSString).characterAtIndex(0)
    let LOWCASE_Z = ("z" as NSString).characterAtIndex(0)
    if ch >= LOWCASE_A && ch <= LOWCASE_Z {...whatever...}
    
    let myChar='f'//类型为字符,值仅为unicode U+0066拉丁小写字母f
    设myInt8:Int8='f'//类型为Int8,值为102(0x66)
    让myUInt8Array:[UInt8]=['a','b','1','2']//类型为[UInt8],值为[97,98,49,50]([0x61,0x62,0x31,0x32])
    切换到某处{
    大小写“a”…“f”:返回“小写十六进制字母”
    大小写“A”…“F”:返回“大写十六进制字母”
    案例“0”…“9”:返回“十六进制数字”
    默认值:返回“非十六进制字符”
    }
    
    为什么我要挖掘7年前的帖子?我想很有趣吧?不过说真的,我想我可以加入讨论

    它不是一个漏洞,或者更确切地说,它是一个故意的漏洞,明确阻止将文本字符串与ASCII字节序列合并

    您完全可以分离字符串。字符串实现了双向集合,并且有许多方法可以操作原子。请参阅:。 但你必须习惯更广义的字符串概念。它可以从用户视角(这是一系列的图形集簇,每个(通常)都是视觉上可分离的外观)中分离出来,也可以从编码视角(可以是几个(UTF32、UTF16、UTF8)中的一个)中分离出来

    冒着过度分析问题措辞的风险:

    • 数据结构是概念性的,与存储中的编码无关
    • 编码为ASCII字符串的数据结构只是ASCII字符串的一种
    • 通过设计,ASCII值0-127的编码在UTF-8中具有相同的编码,因此使用UTF8API加载该流是可以的
    • 编码为字符串的数据结构(其中结构字段具有UTF-8 Unicode字符串值)不是ASCII字符串,而是UTF-8字符串本身
    • 字符串是ASCII编码还是非ASCII编码;“出于实际目的”不是一个有意义的限定符。如果UTF-8数据库字段中99.99%的文本在ASCII范围内(编码将匹配),但偶尔不匹配,则会出现一些严重的错误
    而不是固定宽度整数和仅英语的简洁和低级等价
    let foo = "abcDeé@¶œŎO!@#"
    
    foo.forEach { c in
        print((c.isASCII ? "\(c) is ascii with value \(c.asciiValue ?? 0); " : "\(c) is not ascii; ")
            + ((c.isLetter ? "\(c) is a letter" : "\(c) is not a letter")))
    }
    
    b is ascii with value 98; b is a letter
    c is ascii with value 99; c is a letter
    D is ascii with value 68; D is a letter
    e is ascii with value 101; e is a letter
    é is not ascii; é is a letter
    @ is ascii with value 64; @ is not a letter
    ¶ is not ascii; ¶ is not a letter
    œ is not ascii; œ is a letter
    Ŏ is not ascii; Ŏ is a letter
    O is ascii with value 79; O is a letter
    ! is ascii with value 33; ! is not a letter
    @ is ascii with value 64; @ is not a letter
    # is ascii with value 35; # is not a letter