Swift Basic grammar Question

Hi there
Sometimes wonder why use .abcd() but something use efgh: .abcd
For example : .rotationEffect(.degrees(30), anchor: .bottom)
I heard '.abcd ' is (rotaitonEffect) degrees so that front of function name is omitted But anchor is not ' (rotaitonEffect) anchor ' but (anchor) bottom '
so how should I think ' : ' things and ' . ' thing are different?
Why I can't use .anchor(bottom)? or : degrees(30)

Good question! You can get a bit of a hint by looking at the actual declaration of the rotationEffect function in the docs:

func rotationEffect(
    _ angle: Angle,
    anchor: UnitPoint = .center
) -> some View

The first thing worth noting is that anchor: here is part of the declaration of the rotationEffect function—in Swift, function arguments are (often) labeled, though as you note it is common for function declarations omit the label for the first argument (see the Swift API Design Guidelines for more detail). So in a function call like:

rotationEffect(.degrees(30), anchor: .bottom)

what we're doing is calling the function and passing two arguments. The first one, .degrees(30), is unlabeled, and the second, .bottom, is labeled with the label anchor:. You will sometimes see the full name of the rotationEffect function written out as rotationEffect(_:anchor:).

The other part of your question which deserves some explanation is what's going on with the . in .degrees(30) and .bottom. This is called an implicit member expression and you use it to access static members of a type which return a value of the type itself. You see this commonly with enum cases but even non-enum types can leverage this behavior to make convenient factory functions available.

If you look at the docs for the Angle type used in rotationEffect, you can see that it defines several static members:

Getting constant angles

static var zero: Angle
static func degrees(Double) -> Angle
static func radians(Double) -> Angle

Since all of these return values of type Angle, you can use the implicit member syntax in positions that expect a value of type Angle. As you've seen, you can write .degrees(30), but you could also write .zero, or even nest implicit member expressions to write something like .radians(.pi / 6.0). In that last one, because the radians function expects an argument of type Double, and the division operator / also expects an argument (and produces a return value) of type Double, we're able to use the static member pi of Double, which provides a convenient way to access the constant value π.

9 Likes

Thanks
bunch of swift books didn't let me know Basic logic

Just to add:

rotationEffect(.degrees(30), anchor: .bottom)

can also be written

rotationEffect(Angle.degrees(30), anchor: UnitPoint.bottom)

Since the compiler knows the type of angle is Angle and the type of anchor is UnitPoint you can leave off the explicit types where the compiler has to look for static func degrees() and static let bottom: UnitPoint

4 Likes

Was this used like that in Object-C ?

No, as Objective-C does not have type inference.