将我的类型转换为预期的参数类型
Convert my type to expected argument type
我正在使用 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
变量中填充它,该变量是从选择器中填充的。虽然我知道我可以从 Size
创建一个新的 SizeInput
,但我更愿意将 Size
传递到查询中,因为它们本质上是相同的,只是两种不同的类型。截至目前,XCode 显然抱怨 Cannot convert value of type 'Size' to expected argument type 'SizeInput'
关键是我不能(不想)更改 Apollo 函数,因为它是自动生成的。所以我理想的解决方案是以某种方式将 Size
类型转换为 SizeInput
,但是 XCode 抱怨如果我只是尝试做 let sizeInput = size as? SizeInput
其中 size
是 Size
.
假设我无法修改接受参数的函数并且我无法修改 SizeInput
因为两者都是自动生成的,我如何修改 Size
以便它可以用作 SizeInput
参数?
Size
和 SizeInput
根据您的 post 是两种不同的类型,因此不能按照您的想法进行类型别名。
Swift's Declarations reference 关于 typealias
的说法如下:
A type alias declaration introduces a named alias of an existing type into your program. [...] After a type alias is declared, the aliased name can be used instead of the existing type everywhere in your program. [...] Type aliases do not create new types; they simply allow a name to refer to an existing type.
...但这不是您想要的。 Size
和 SizeInput
在合同上很相似,因为它们有一个 cm: Double
属性,但在结构上是不同的,不能互换使用。
无论选择哪种解决方案,您都需要做出一些权衡。我至少看到以下选项。
- 您可以编写一个位于代码生成 GraphQL 内容之上的层,提供您想要的界面(即采用
Size
)并使用它。然后将您的 Size
翻译成 SizeInput
。可以使用代码生成器。
- 您可以在
Size
类型本身上提供 Size
到 SizeInput
的某种类型级函数,然后在您的 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)
对于我的 $,我会选择编写尽可能少的额外代码。
YMMV
我正在使用 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
变量中填充它,该变量是从选择器中填充的。虽然我知道我可以从 Size
创建一个新的 SizeInput
,但我更愿意将 Size
传递到查询中,因为它们本质上是相同的,只是两种不同的类型。截至目前,XCode 显然抱怨 Cannot convert value of type 'Size' to expected argument type 'SizeInput'
关键是我不能(不想)更改 Apollo 函数,因为它是自动生成的。所以我理想的解决方案是以某种方式将 Size
类型转换为 SizeInput
,但是 XCode 抱怨如果我只是尝试做 let sizeInput = size as? SizeInput
其中 size
是 Size
.
假设我无法修改接受参数的函数并且我无法修改 SizeInput
因为两者都是自动生成的,我如何修改 Size
以便它可以用作 SizeInput
参数?
Size
和 SizeInput
根据您的 post 是两种不同的类型,因此不能按照您的想法进行类型别名。
Swift's Declarations reference 关于 typealias
的说法如下:
A type alias declaration introduces a named alias of an existing type into your program. [...] After a type alias is declared, the aliased name can be used instead of the existing type everywhere in your program. [...] Type aliases do not create new types; they simply allow a name to refer to an existing type.
...但这不是您想要的。 Size
和 SizeInput
在合同上很相似,因为它们有一个 cm: Double
属性,但在结构上是不同的,不能互换使用。
无论选择哪种解决方案,您都需要做出一些权衡。我至少看到以下选项。
- 您可以编写一个位于代码生成 GraphQL 内容之上的层,提供您想要的界面(即采用
Size
)并使用它。然后将您的Size
翻译成SizeInput
。可以使用代码生成器。 - 您可以在
Size
类型本身上提供Size
到SizeInput
的某种类型级函数,然后在您的 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)
对于我的 $,我会选择编写尽可能少的额外代码。
YMMV