我不知道 Swift 返回值是啥
Posted
技术标签:
【中文标题】我不知道 Swift 返回值是啥【英文标题】:I don't know what the Swift return value would be我不知道 Swift 返回值是什么 【发布时间】:2019-02-12 15:11:42 【问题描述】:Xcode 说要输入一个返回值,但我不知道要使用什么返回值。
func getCurrentTimelineEntry(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationTimelineEntry?) -> Void)
let entry = CLKComplicationTimelineEntry(date: Date(), complicationTemplate: constructTemplate(for: complication))
handler(entry)
func getLocalizableSampleTemplate(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationTemplate?) -> Void)
handler(constructTemplate(for: complication))
private func constructTemplate(for complication: CLKComplication) -> CLKComplicationTemplate
switch complication.family
case .modularSmall:
let template = CLKComplicationTemplateModularSmallSimpleText()
let provider = CLKSimpleTextProvider(text: GioTexts.TitleLeft.rawValue)
template.textProvider = provider
return template
case .modularLarge:
let t = CLKComplicationTemplateModularLargeStandardBody()
t.headerImageProvider = CLKImageProvider(onePieceImage: UIImage(named: "Complication/Circular")!)
t.headerTextProvider = CLKSimpleTextProvider(text: GioTexts.TitleLeft.rawValue)
t.body1TextProvider = CLKSimpleTextProvider(text: GioTexts.SubtitleLeft.rawValue)
t.body2TextProvider = CLKSimpleTextProvider(text: GioTexts.SubtitleRight.rawValue)
return t
case .extraLarge:
let t = CLKComplicationTemplateExtraLargeColumnsText()
t.row1Column2TextProvider = CLKSimpleTextProvider(text: GioTexts.TitleLeft.rawValue)
t.row1Column1TextProvider = CLKSimpleTextProvider(text: "")
t.row2Column2TextProvider = CLKSimpleTextProvider(text: GioTexts.SubtitleLeft.rawValue)
t.row2Column1TextProvider = CLKSimpleTextProvider(text: GioTexts.SubtitleRight.rawValue)
t.column2Alignment = .trailing
return t
case .utilitarianSmallFlat, .utilitarianSmall:
let t = CLKComplicationTemplateUtilitarianSmallFlat()
t.imageProvider = CLKImageProvider(onePieceImage: UIImage(named: "Complication/Circular")!)
t.textProvider = CLKSimpleTextProvider(text: GioTexts.TitleLeft.rawValue)
return t
case .utilitarianLarge:
let t = CLKComplicationTemplateUtilitarianLargeFlat()
t.textProvider = CLKSimpleTextProvider(text: GioTexts.TitleLeft.rawValue)
return t
case .circularSmall:
let t = CLKComplicationTemplateCircularSmallStackImage()
t.line1ImageProvider = CLKImageProvider(onePieceImage: UIImage(named: "Complication/Circular")!)
t.line2TextProvider = CLKSimpleTextProvider(text: GioTexts.TitleLeft.rawValue)
return t
case .graphicCorner: break
case .graphicBezel: break
case .graphicCircular: break
case .graphicRectangular: break
错误:
【问题讨论】:
这不是关于 Xcode,而是关于编程语言、我假设的 swift 和编译器。 您得到了两个很好的答案,请您选择一个吗?回答的人都是好人,值得被点赞。 【参考方案1】:您的方法已定义为返回CLKComplicationTemplate
,但您的最后四个case
子句只是break
,不返回任何内容。
由于使用此实用程序方法的CLKComplicationDataSource
方法都接受可选项,因此您只需定义此方法以返回可选项(即CLKComplicationTemplate?
)并让这四种情况返回nil
:
func getCurrentTimelineEntry(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationTimelineEntry?) -> Void)
let entry = constructTemplate(for: complication).flatMap
CLKComplicationTimelineEntry(date: Date(), complicationTemplate: $0)
handler(entry)
func getLocalizableSampleTemplate(for complication: CLKComplication, withHandler handler: @escaping (CLKComplicationTemplate?) -> Void)
handler(constructTemplate(for: complication))
private func constructTemplate(for complication: CLKComplication) -> CLKComplicationTemplate?
switch complication.family
case .modularSmall:
...
case .modularLarge:
...
case .extraLarge:
...
case .utilitarianSmallFlat, .utilitarianSmall:
...
case .utilitarianLarge:
...
case .circularSmall:
...
case default:
return nil
【讨论】:
case .graphicCorner, .graphicBezel, .graphicCircular, .graphicRectangular
=> default
@matt IMO 的任何一种方法都有很好的论据。在这种特殊情况下,我更喜欢 Rob 的方法,因为如果添加了新案例,它会迫使我重新考虑代码。这也是支持默认设置的一个原因,所以它真的只是 IMO 的风格。
@matt - 是的,我可能会使用default
(尤其是考虑到 Swift 5 中即将出现的未知案例)。我只是试图做最适度的改变来解决 OP 的问题。不过default
这里比较谨慎,我也做了相应的调整。【参考方案2】:
你的函数声称返回一个CLKComplicationTemplate
,所以在所有情况下它都必须这样做,否则它不能返回。如果在任何情况下无法返回您承诺的类型的值,您唯一的其他合理选择是使程序崩溃,最常见的是调用fatalError
。 (从技术上讲,您也可以阻止该函数,使其永远不会返回,例如通过进入无限循环,但这通常不是一个有用的解决方案。)
这为您留下了许多前进的选择:
如果有一些合理的默认值,您可以将其返回以处理未处理的复杂情况。 如果您认为将无效的并发症传递给此函数是一个编程错误,那么在这些情况下调用fatalError()
是合理的。例如,访问超出其边界的数组索引是一个编程错误,并且以这种方式使程序崩溃。您绝不应该这样做以响应来自系统外部的数据(例如配置数据)。
您可以更改此方法以接受仅包含您支持的案例的枚举,而不是传递整个复杂情况。这使得错误地调用它是不可能的,并且通常比调用 fatalError
更可取。
如果传递无效的并发症是可以接受的,但不应该做任何事情,那么您应该更改方法以返回CLKComplicationTemplate?
并让调用者决定如何处理它。例如,如果你在一个空数组上调用.first
,你会得到 nil。这不是错误;就是没有这样的元素。
如果传递无效的并发症是错误,但应该由调用者处理(例如,如果它来自配置数据),那么您应该更改此方法以添加 throws
并在这些情况下抛出错误.例如,尝试打开不存在的文件会引发错误。这是错误的,但这不是编程错误。如果您希望调用者了解出了什么问题,这将特别有用。您可以将throws
视为将承诺的返回类型更改为“返回值或引发的错误”。
【讨论】:
以上是关于我不知道 Swift 返回值是啥的主要内容,如果未能解决你的问题,请参考以下文章
如何知道xmlhttp的responsetext返回值是啥?