我如何避免将这 3 行写两次?

How do i avoid writing these 3 lines twice?

考虑在 SwiftUI 中进行以下扩展:

extension Text{
   func applyBG() -> some View {
      self
         .padding(20)
         .background(Color(hue: 0, saturation: 0, brightness: 0.22).cornerRadius(10))
         .foregroundColor(.white)
   }
}

extension TextField{
   func applyBG() -> some View {
      self
         .padding(20)
         .background(Color(hue: 0, saturation: 0, brightness: 0.22).cornerRadius(10))
         .foregroundColor(.white)
   }
}

我觉得我可以写得更好,避免重复。 我可能可以用类似的方法解决这个问题:

extension View{
   func applyBG() -> some View {
      self
         .padding(20)
         .background(Color(hue: 0, saturation: 0, brightness: 0.22).cornerRadius(10))
         .foregroundColor(.white)
   }
}

但我不希望我的所有视图都能够调用此方法。 我只希望 Text 和 Textfield 有这样的方法。我尝试使用协议和关联类型,但为了获得干净的代码,我无法只写一次这些行。 关于如何实现 DRY 的任何提示或伪代码?

你可以在协议上声明函数,只需将其 return 类型从 some View 更改为 AnyView,然后使 TextTextField 符合此协议。

protocol TextView: View {
    func applyBackground() -> AnyView
}

extension TextView {
    func applyBackground() -> AnyView {
        AnyView(padding(20)
                    .background(Color(hue: 0, saturation: 0, brightness: 0.22).cornerRadius(10))
                    .foregroundColor(.white)
        )
    }
}

extension Text: TextView {}
extension TextField: TextView {}

Text("text").applyBackground()

像这样使用协议:

import SwiftUI

protocol BGApplyable where Self: View {}

extension BGApplyable {
  func applyBG() -> some View {
    self
     .padding(20)
     .background(Color(hue: 0, saturation: 0, brightness: 0.22).cornerRadius(10))
     .foregroundColor(.white)
  }
}

决定哪些视图可以采用协议:

extension TextField: BGApplyable {}
extension Text: BGApplyable {}

然后使用它:

var body: some View {
  VStack {
    Text("Foo")
      .applyBG()
    TextField("Hello", text: .constant("World!"))
      .applyBG()
  }
}