Swift: แปลงค่า enum เป็น String หรือไม่


141

รับ enum ต่อไปนี้:

enum Audience {
    case Public
    case Friends
    case Private
}

ฉันจะรับสาย"Public"จากaudienceค่าคงที่ด้านล่างได้อย่างไร

let audience = Audience.Public

2
โปรดตรวจสอบคำตอบนี้อาจทำให้คุณมีความคิดเกี่ยวกับวิธีที่คุณสามารถบรรลุสิ่งดังกล่าว: stackoverflow.com/questions/24648726/enums-with-data-in-swift/…
holex

ใน Swift 2 และ xcode7 คุณไม่จำเป็นต้องเปลี่ยนอะไรเป็นรหัสของคุณเพียงแค่ใช้print("\(audience)")
gbdavid

7
ฉันเกลียดที่ Ecoscape Swift ตอนนี้เต็มไปด้วยคำตอบที่เก่ามากเช่นนี้ ในฐานะของ XCode8.2 / Swift3 มันง่ายเหมือนString(describing: yourEnumValue)
Travis Griggs

@TravisGriggs ใช้งานไม่ได้กับ Xcode 11.4 อีกต่อไป
DawnSong

มีความเป็นไปได้ที่ซ้ำกันของวิธีรับชื่อค่าการแจงนับใน Swift
pkamb

คำตอบ:


156

ไม่แน่ใจว่าเพิ่มฟีเจอร์นี้ใน Swift เวอร์ชันใด แต่ตอนนี้ ( Swift 2.1 ) คุณต้องใช้รหัสนี้เท่านั้น:

enum Audience : String {
    case public
    case friends
    case private
}

let audience = Audience.public.rawValue // "public"

เมื่อสตริงถูกใช้สำหรับค่าดิบค่าโดยนัยสำหรับแต่ละเคสคือข้อความของชื่อของเคสนั้น

[ ... ]

enum CompassPoint : String {
    case north, south, east, west
}

ในตัวอย่างข้างต้น CompassPoint.south มีมูลค่าดิบโดยนัยเป็น "ใต้" และอื่น ๆ

คุณเข้าถึงค่า raw ของเคสการแจงนับด้วยคุณสมบัติ rawValue:

let sunsetDirection = CompassPoint.west.rawValue
// sunsetDirection is "west"

แหล่ง


8
ใน xcode7.3 swift2.2 ถ้าฉันทำสิ่งต่าง ๆ เช่น: print("appState: \(application.applicationState)") ฉันได้รับ appState: UIApplicationState ซึ่งเป็นประเภทและไม่ได้เป็นตัวแทนสตริงที่แท้จริงของค่า Enum ฉันทำอะไรบางอย่างหายไปหรือเปล่า (PS: สำหรับ rawValue ฉันเพิ่งได้รับค่า Int ... )
Martin

@Cyrus สถานการณ์ของคุณแตกต่างจากที่ถามในกระทู้นี้ .rawValueจะคืนค่าดิบของ enum ของคุณ คุณเป็นpublic enum UIApplicationState : IntประเภทIntไหนแน่นอน คุณยังไม่เคยอ่านคำตอบของฉันซึ่งมีใบเสนอราคาจากเอกสารของ Apple ... หากคุณยังต้องการที่จะแปลงUIApplicationStateเป็นสตริงฉันขอแนะนำให้คุณขยายUIApplicationStateด้วยคุณสมบัติการคำนวณที่กำหนดเองextension UIApplicationState { var toString() -> String { /* check self for all diff. cases and return something like "Active" */ }
DevAndArtist

ไม่สามารถแก้ปัญหาด้วยการมี enums ไม่ใช่ประเภท String
denis631

1
@ denis631 คุณหมายถึงอะไร ชนิดดิบของ enum สามารถเป็นอะไรก็ได้ Enum สามารถทำตามได้OptionSetหากคุณต้องการ และคำถามเดิมเกี่ยวกับ Strings ต่อไป
DevAndArtist

1
ถ้า enum ของฉันถูกเขียนเช่นนี้ทดสอบ enum: Int {case A, B}, rawValue แน่นอนว่าจะคืนกลับ int สิ่งที่เรากำลังมองหาเป็นวิธีที่จะได้รับชื่อของคดีเป็นสตริง นี่คือสิ่งที่ @DanilShaykhutdinov ทำ ดูที่คำตอบของเขาและในคำถามเดิม Enum ไม่มีประเภทไม่ใช่ String หรือ Int
denis631

209

อินเทอร์เฟซที่ใช้สำนวนสำหรับ 'การรับสายอักขระ' คือการใช้CustomStringConvertible อินเทอร์เฟซและเข้าถึงตัวdescriptionเรียกใช้ กำหนดของคุณenumเป็น:

enum Foo : CustomStringConvertible {
  case Bing
  case Bang
  case Boom
  
  var description : String { 
    switch self {
    // Use Internationalization, as appropriate.
    case .Bing: return "Bing"
    case .Bang: return "Bang"
    case .Boom: return "Boom"
    }
  }
}

ในการดำเนินการ:

 > let foo = Foo.Bing
foo: Foo = Bing
 > println ("String for 'foo' is \(foo)"
String for 'foo' is Bing

อัปเดต : สำหรับ Swift> = 2.0 แทนที่Printableด้วยCustomStringConvertible

หมายเหตุ : การใช้CustomStringConvertibleอนุญาตให้Fooใช้ชนิด raw อื่นได้ ตัวอย่างenum Foo : Int, CustomStringConvertible { ... }เป็นไปได้ อิสรภาพนี้มีประโยชน์


2
อีกวิธีที่สั้นกว่าในการสร้างสตริง println คือ: "String สำหรับ 'foo' คือ (foo)"
John MP Knox

3
@ JohnM.P.Knox อย่าลืมแบ็กสแลชใน "String สำหรับ 'foo' คือ \ (foo)" แก้ไขตกลงมันเป็นตัวแก้ไขกำจัดฉันต้องป้อน 2 รายการเพื่อให้ปรากฏขึ้น
zmit

มันจะมีประโยชน์อะไรCustomStringConvertibleถ้ามันใช้ได้ดีโดยไม่มีมัน?
Daniel van der Merwe

3
CustomStringConvertibleอนุญาต / กำหนดให้คุณต้องกำหนดdescriptionว่าจะให้คุณตัดสินใจว่าจะใช้สตริงตัวใดสำหรับแต่ละกรณี enum - นี่เป็นสิ่งสำคัญสำหรับการทำให้เป็นสากลอย่างแน่นอน หากคุณไม่สนใจสิ่งเหล่านั้นคุณสามารถใช้ 'enum Foo: String {/ * ... * /} `
GoZoner

2
นี่เป็นคำตอบที่ถูกต้องหาก enum ของคุณไม่ใช่ String หรือคุณต้องการสตริงที่แตกต่างจากนั้น rawValue @ denis631
Haagenti

32

สำหรับตอนนี้ฉันจะกำหนด Enum ใหม่เป็น:

enum Audience: String {
    case Public = "Public"
    case Friends = "Friends"
    case Private = "Private"
}

ดังนั้นฉันสามารถทำ:

audience.toRaw() // "Public"

แต่นิยาม enum ใหม่นี้ไม่ซ้ำซ้อนหรือไม่ ฉันสามารถกำหนดนิยาม enum เริ่มต้นและทำสิ่งที่ชอบ:

audience.toString() // "Public"

3
ในฐานะของ Xcode 7 Beta 3 คุณสามารถเขียนคำตอบของคุณได้โดยไม่ต้องมี= Stringเพราะมันจะได้รับค่าดิบโดยอัตโนมัติ (ชื่อของกรณี) ถ้าคุณไม่ได้ให้
Qbyte

3
แทน. toString () ตอนนี้ใช้ .rawValue
SoftDesigner

ใน Swift 1.2 คุณสามารถใช้: println (Audience.Friends.rawValue)
Oleg Popov

32

ใน swift 3 คุณสามารถใช้สิ่งนี้

var enumValue = Customer.Physics
var str = String(describing: enumValue)

จากSwift วิธีใช้ enum เพื่อรับค่าสตริง


2
สิ่งนี้มีประโยชน์จริง ๆ โดยเฉพาะถ้าฉันenumไม่ได้ใช้Strings
daspianist

1
"\(enumValue)"ทำสิ่งเดียวกัน ^^
eonist

นี่เป็นคำตอบที่ดีกว่า ไม่จำเป็นต้องสร้าง enum String ของคุณ
scord

24

ผมชอบที่จะใช้กับPrintableRaw Values

enum Audience: String, Printable {
    case Public = "Public"
    case Friends = "Friends"
    case Private = "Private"

    var description: String {
        return self.rawValue
    }
}

จากนั้นเราสามารถทำได้:

let audience = Audience.Public.description // audience = "Public"

หรือ

println("The value of Public is \(Audience.Public)") 
// Prints "The value of Public is Public"

1
ฉันชอบวิธีนี้ดีกว่าคำตอบที่เลือกเพราะฉันสามารถทำได้Audience(rawValue: "Friends")
tidwall

12

อัปเดตสำหรับการเปิดตัว Xcode 7 GM มันทำงานได้อย่างที่หวังตอนนี้ - ขอบคุณ Apple!

enum Rank:Int {
    case Ace = 1, Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King
}

let r = Rank.Ace

print(r)               // prints "Ace"
print("Rank: \(r)!")   // prints "Rank: Ace!"

2
ใน Swift 2.0 การปฏิบัติตามCustomStringConvertibleจะอนุญาตให้ใช้ได้จริงprint(r)ในกรณีนี้
matm

ใน Xcode 7 เบต้า 4 ดูเหมือนว่า () จะถูกปิดใช้งานแทน Mirror (สะท้อนถึง: x) อย่างไรก็ตามวัตถุที่ส่งคืนมีโครงสร้างที่แตกต่างกัน
GSnyder

1
อัปเดตคำตอบโปรด
เบ็นซินแคลร์

10

มันไม่ง่ายไปกว่านี้ใน Swift 2 และ Xcode 7 ล่าสุด (ไม่จำเป็นต้องระบุประเภท enum หรือ. avValue, descriptors ฯลฯ ... )

อัปเดตสำหรับ Swift 3 และ Xcode 8:

    enum Audience {
        case Public
        case Friends
        case Private
    }

    let audience: Audience = .Public  // or, let audience = Audience.Public
    print(audience) // "Public"

ทำงานอย่างสมบูรณ์แบบด้วย Int ของฉันได้รับการสนับสนุน enums
chrislarson

เพียงแค่การสังเกต: สิ่งนี้ใช้ได้กับ enums ที่สร้างขึ้นด้วยตนเอง แต่ไม่ได้ผลกับบางอย่างเช่น HKWorkoutActivityType
Ace Green

เช่นเดียวกับการ จำกัด สาย;)
ยูจีน Braginets

2
คำถามดั้งเดิมเกี่ยวกับการแปลงค่า enum เป็นสตริงใน enums ของคุณเองนั่นคือสิ่งที่ฉันให้คำตอบสำหรับ ... ถ้าคุณต้องการจัดการ UIKit / AppKit Enums แน่นอนว่ามันเป็นเรื่องที่แตกต่าง
gbdavid

1
@gbdavid - มี Q สำหรับ UIKit / AppKit Enums หรือไม่? ฉัน googled และหาไม่พบ ฉันสามารถส่ง Q หากจำเป็น
benc

8

ตัวอย่างที่รวดเร็วและเหนือกว่าหากใช้ Ints in Enum

public enum ECategory : Int{
        case Attraction=0, FP, Food, Restroom, Popcorn, Shop, Service, None;
        var description: String {
            return String(describing: self)
        }
    }

let category = ECategory.Attraction
let categoryName = category.description //string Attraction

ทางออกที่สง่างาม "\ (หมวดหมู่)" หรือสตริงโดยตรง (อธิบาย: หมวดหมู่) ก็สามารถใช้ได้เช่นกัน แม้แต่ Int enums
t1ser

8

สำหรับทุกคนที่อ่านตัวอย่างในบท "A Swift Tour" ของ "ภาษา Swift Programming" และมองหาวิธีที่จะลดความซับซ้อนของเมธอด simpleDescription () การแปลง enum ให้เป็น String โดยการทำString(self)จะทำ:

enum Rank: Int
{
    case Ace = 1 //required otherwise Ace will be 0
    case Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten
    case Jack, Queen, King
    func simpleDescription() -> String {
        switch self {
            case .Ace, .Jack, .Queen, .King:
                return String(self).lowercaseString
            default:
                return String(self.rawValue)
        }
     }
 }

2
เพียงให้แน่ใจว่าคุณไม่ได้ใช้ enum กับ "@objc" นั่นทำให้วิธีการนี้ล้มเหลว
Matt Bearson

5

หลังจากลองใช้วิธีต่าง ๆ ไม่กี่ฉันพบว่าถ้าคุณไม่ต้องการใช้:

let audience = Audience.Public.toRaw()

คุณยังสามารถเก็บถาวรได้โดยใช้ struct

struct Audience {
   static let Public  = "Public"
   static let Friends = "Friends"
   static let Private = "Private"
}

จากนั้นรหัสของคุณ:

let audience = Audience.Public

จะทำงานตามที่คาดไว้ มันไม่สวยและมีข้อเสียเพราะคุณไม่ได้ใช้ "enum" คุณไม่สามารถใช้ทางลัดเพียงเพิ่มเท่านั้นส่วนบุคคลไม่สามารถใช้กับกรณีสวิตช์ได้


ดูเรียบร้อย ฉันสงสัยว่าอะไรจะเป็นวิธีปฏิบัติที่ดีที่สุดสำหรับกรณีนี้ ฉันชอบที่จะใช้ไวยากรณ์ของ struct เพราะความเรียบง่าย แต่การใช้ struct แทนที่จะเป็น enum ดูไม่ถูกต้องหรืออาจเป็นแค่ฉัน ทีนี้ไม่มีสิ่งใดที่จะป้องกันคุณในการประกาศตัวแปรคงที่ที่ใดก็ได้คราวนี้คุณแค่เพิ่มมันเข้าไปใน struct เพื่อจัดระเบียบมัน คิด?
schystz

แน่นอนมันทำงานเป็นตัวแปรคงที่ แต่มีการจัดระเบียบมากขึ้น อย่างที่ฉันพูดไว้ก่อนหน้าปัญหาเดียวคือ "switch case" และทางลัด ".Private" หากคุณกำลังสร้างแอปของคุณขึ้นมาให้ลองใช้ "enum" ใช้ struct เฉพาะเมื่อ "enum" ไม่ตรงกับรหัสของคุณด้วยเหตุผลบางประการ ฉันเป็นการหลีกเลี่ยงตัวแปรค่าคงที่และใช้โครงสร้างแทนเสมอ
Adriano Spadoni

ฉันใช้สิ่งนี้เป็นกุญแจเริ่มต้น แทนที่จะจดจำคีย์เริ่มต้นภายในแอพฉันจะถ่ายโอนคีย์ในโครงสร้างและดึงออกมาจากที่นั่น
Adrian

3

มีหลายวิธีในการทำเช่นนี้ คุณสามารถกำหนดฟังก์ชันใน enum ซึ่งจะส่งคืนสตริงตามค่าของชนิด enum:

enum Audience{
    ...
func toString()->String{
  var a:String

  switch self{
   case .Public:
    a="Public"
   case .Friends:
    a="Friends"
   ...
 }
 return a
}

หรือคุณสามารถลองทำสิ่งนี้:

enum Audience:String{
   case Public="Public"
   case Friends="Friends"
   case Private="Private"
}

และใช้มัน:

var a:Audience=Audience.Public
println(a.toRaw())

1

เริ่มจาก Swift 3.0 ที่คุณทำได้

var str = String(describing: Audience.friends)

1
ไม่น่าเชื่อ แต่ใช้งานได้ดี สั้นกว่าวิธี "สำนวน" มาก ขอบคุณ!
โรมัน
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.