我想创建一个具有以下功能的协议
@ViewBuilder
func navigate<T: View>(content: () -> T) -> some View {
switch self{
case .list:
NavigationLink(destination: Text("Test")){ content() }
default:
EmptyView()
}
}
这是我的尝试,但不起作用
protocol Test {
associatedtype Result: View
func navigate<T: View>(content: () -> T) -> Result
}
答案 0 :(得分:1)
Opaque Result Types 提案的 Associated Type Inference 部分明确不允许这样做。来自提案:
<块引用>关联类型推断只能为非泛型需求推断出不透明的结果类型,因为不透明类型是由函数自己的泛型参数参数化的。例如,在:
protocol P {
associatedtype A: P
func foo<T: P>(x: T) -> A
}
struct Foo: P {
func foo<T: P>(x: T) -> some P {
return x
}
}
没有单一的底层类型可以推断 A,因为 foo 的返回类型可以随 T 改变。
为了使您的问题更具体,为了符合 Test
,必须只有一种类型可以分配给 Result
。但是,您的返回类型是通用的,因此它取决于传递的内容。 navigate
的实际(非不透明)返回类型是:
_ConditionalContent<NavigationLink<T, Text>, EmptyView>
但是 T
是一个类型参数,会根据 navigate
的调用方式而变化。所以没有一种类型可以分配给 Result
。
您需要可以返回单个非参数化类型的东西。对于您给出的示例,可能是 AnyView,这很烦人。
也就是说,你在这里写的东西感觉起来不像是一个协议。它看起来很像一个函数。我想了很多关于 navigate
可以写多少种不同的方式。如果每个人都以相同的方式实现它,那只是一个功能。 (如果您再举一个符合类型的示例,可能有助于设计更好的方法。)
答案 1 :(得分:0)
您可以在目的地调用它的地方执行此操作。
extension View {
func navigate< Destination: View, Label: View>(content: Label) -> some View {
NavigationLink(destination: Destination) { content. }
}
}
问题是您无法在方法中找到调用者,因为您正在扩展协议。