如何解决将我的类型转换为预期的参数类型
我正在使用 Apollo Client 在 Xcode 中自动生成 graphql 类型和查询,但遇到了一个我不知道如何最好地解决的问题。 TLDR 是如何允许将一个结构用作接受具有相同结构的另一种类型的函数的参数?
Apollo 为我生成了一个名为“SizeInput”的结构,如下所示:
struct SizeInput: GraphQLMapConvertible {
public var graphQLMap: GraphQLMap
public init(cm: Double) {
graphQLMap = ["cm": cm]
}
public var cm: Double {
get {
return graphQLMap["cm"] as! Double
}
set {
graphQLMap.updateValue(newValue,forKey: "cm")
}
}
}
(顺便说一句 - GraphQLMap
是 [String : JSONEncodable?]
的类型别名)
我创建了一个 Size
结构用于我的代码。我不想在我的代码中使用 SizeInput
来将后端与我的应用代码分开,这样在后端或应用发生变化时事情就不会中断。
struct Size {
let cm: Double
}
我需要运行一个以 SizeInput
作为参数的 apollo 查询,我想从我的 Size
变量中填充它,该变量是从选择器填充的。虽然我知道我可以从 SizeInput
创建一个新的 Size
,但我很乐意将 Size
传递到查询中,因为它们本质上是相同的,只是两种不同的类型。截至目前,XCode 显然抱怨 Cannot convert value of type 'Size' to expected argument type 'SizeInput'
关键是我不能(不想)改变 Apollo 函数,因为它是自动生成的。所以我的理想解决方案是以某种方式将 Size
类型转换为 SizeInput
,但是如果我只是尝试执行 let sizeInput = size as? SizeInput
其中 size
是 Size
,XCode 会抱怨。
假设我不能修改接受参数的函数,也不能修改 SizeInput
因为两者都是自动生成的,我如何修改 Size
以便它可以用作 {{1} } 论据?
解决方法
Size
和 SizeInput
根据您的帖子是两种不同的类型,因此不能按照您的想法设置别名。
Swift's Declarations reference 关于 typealias
的说明如下:
类型别名声明将现有类型的命名别名引入到您的程序中。 [...] 声明类型别名后,可以使用别名代替程序中任何地方的现有类型。 [...] 类型别名不会创建新类型;它们只是允许名称引用现有类型。
...但这不是你想要的。 Size
和 SizeInput
在合同上相似,因为它们具有 cm: Double
属性,但在底层结构上不同,不能互换使用。
无论选择哪种解决方案,您都需要进行一些权衡。我至少看到以下选项。
- 您可以编写一个位于代码生成 GraphQL 内容之上的层,该层提供您想要的接口(即采用
Size
)并使用它。然后将您的Size
翻译成SizeInput
。可以使用 Codegen。 - 您可以在
Size
类型本身上提供某种类型级别的SizeInput
到Size
函数,然后在您的 GraphQL 调用站点中使用它。 Codegen 也可以在这里使用。
extension Size {
func asSizeInput() -> SizeInput {
return SizeInput(cm: cm)
}
}
- 您也可以在调用站点进入 GraphQL,只需将
Size
实例的cm
属性传递给SizeInput
的构造函数,然后您就不会编写任何额外的代码。这是一些伪代码:
let size = Size(cm: 100)
let query = SizeInputGraphQLQuery(sizeInput: size.cm)
对于我的 $,我会选择编写尽可能少的额外代码。
天啊
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。