无法将表达式类型 'Dictionary' 转换为类型 'StringLiteralConvertible'

Cannot convert expression type 'Dictionary' to type 'StringLiteralConvertible'

我正在尝试在 swift 中创建字典,但出现错误。我尝试通过添加“?”来展开变量。不确定创建字典的正确方法

class Event: NSObject {

// When I remove the '?' on the variables it works but im not quite sure why
// Should I not be declaring variable as optional unwrapped?

var title:String?
var eventDescription:String?
var duration:Double?
var eventID:String?
var hostID:String?
var location:CLLocation?
var category:String?
var invitedUsers:[String?]

func createEvent(){

    // setting up event information to save
    var postEventData = [
        "title": self.title,
        "description":self.eventDescription,
        "duration":self.duration,
        "host":self.hostID,
        "category":self.category
    ]

}
func setTitle(title:String?){
    self.title = title
}

func setEventDescription(eventDescription:String?){
    self.eventDescription = eventDescription
}
 .....
}

我想它不会让您那样使用它,因为类型带有“?”意味着它是可选的,因此它可能是不安全的,因为内部可能为 nil。 您应该首先检查这些属性是否为 nil,然后显式或隐式地解包它们以供以后在字典中使用。

...
var category:String?

if let cat = self.category? {

    // setting up event information to save
    var postEventData = [
        "category":cat
    ]
 }

在我的示例中,您可以看到我只将类别设为可选,然后将其解包并用于您的字典。它工作正常,因为在 "category" 键下不会有 nil 值进入。

已修复以便更清楚地理解。

首先,您需要一个非可选属性的初始化程序,其次,Swift 字典需要具有相同特定类型的所有键和值。

class Event: NSObject {

    // When I remove the '?' on the variables it works but im not quite sure why
    // Should I not be declaring variable as optional unwrapped?

    // initialiser because of non-optional property
    override init() {
        self.invitedUsers = []
    }

    var title:String?
    var eventDescription:String?
    var duration:Double?
    var eventID:String?
    var hostID:String?
    var category:String?
    var invitedUsers:[String?]

    func createEvent(){

        // setting up event information to save
        // explicitly set the values types as Any
        var postEventData : Dictionary<String, Any> = [
            "title": self.title,
            "description":self.eventDescription,
            "duration":self.duration,
            "host":self.hostID,
            "category":self.category
        ]
    }
}

在这里你说 title(和其他属性)可能有也可能没有值:

var title:String?

那么这里你尝试使用title的值:

var postEventData = [
    "title": self.title,
    "description":self.eventDescription,
    "duration":self.duration,
    "host":self.hostID,
    "category":self.category
]

如果 title 没有值,您需要决定要做什么。应该创建 postEventData 吗?它应该使用默认值吗?理论上你可以创建一个 [String : String?] 的字典,但这通常没有用(因为从字典中获取值已经 return 是可选的)。

所以这里有几个选项,具体取决于您对该数据结构的要求。

  • 使您的属性成为非可选属性。这些属性没有价值真的可以吗?也许他们应该默认为 "" 而不是可选的。

  • 如果设置了所有属性,则只允许 createEvent()(我已将 createEvent 重写为 return 一个值,因为您当前的代码只是创建了一个变量并且然后把它扔掉,所以我不确定目标是什么):


func createEvent() -> [String: String] {
    if let title = self.title,
           description = self.eventDescription,
           duration = self.duration, 
           host = self.hostID,
           category = self.category {
        return [
            "title": title,
            "description": description,
            "duration": duration,
            "host": host,
            "category": category
         ]
     }
     return nil
 }

  • 如果未设置属性,则使用默认值:

func createEvent() -> [String: String] {
    return [
        "title": self.title ?? "", 
        "description": self.eventDescription ?? "",
        "duration": self.duration ?? "",
        "host": self.hostID ?? "",
        "category": self.category ?? ""
    ]
}
  • 或者问问自己为什么要创建字典。你已经有了一个数据结构;你真的需要转换它吗?

附带说明一下,您的 set... 方法没有任何理由。 set 的前缀在 Swift 中具有特殊含义。来电者应该只说 event.title = ...。如果您需要某种特殊的 setter 处理,请使用 set 选项在您的 属性.

上定义它