Swift 3: the Difference Between Public and Internal Access Modifiers

Swift 3: The difference between Public and Internal access modifiers?

Your diagram is just incorrect.

Public members of A.swift and B.swift are available to C.swift and D.swift. The only restriction is that classes can't be subclassed (they would need to be open.

In Swift, what is the difference between the Access modifiers internal and public?

Whatever you marked as public can be use within your app and outside of you app(module). If you marked something as internal that can only be used within your app(module). This is very helpful when your developing a library (framework) , you can use internal to hide library structure.

And Public members of A.swift and B.swift are available to C.swift and D.swift. The only restriction is that classes can't be subclassed (they would need to be open.)
- My answer base on @Keaz & @Alexander.

Public Vs Internal Access Modifier

Swift’s access control model is based on the concept of modules and source files.

A module is a single unit of code distribution—a framework or application that is built and shipped as a single unit and that can be imported by another module with Swift’s import keyword.

For example, some popular modules: Alamofire, SwiftyJson, RxSwift ...
These modules you are importing into your project. All classes that are using internal access level can be used only inside these libs/ modules. You cannot use them directly in your code.
But if the class is public - you can use it in your sources directly.

Does Swift have access modifiers?

As of Swift 3.0.1, there are 4 levels of access, described below from the highest (least restrictive) to the lowest (most restrictive).


1. open and public

Enable an entity to be used outside the defining module (target). You typically use open or public access when specifying the public interface to a framework.

However, open access applies only to classes and class members, and it differs from public access as follows:

  • public classes and class members can only be subclassed and overridden within the defining module (target).
  • open classes and class members can be subclassed and overridden both within and outside the defining module (target).

// First.framework – A.swift

open class A {}

// First.framework – B.swift

public class B: A {} // ok

// Second.framework – C.swift

import First

internal class C: A {} // ok

// Second.framework – D.swift

import First

internal class D: B {} // error: B cannot be subclassed

2. internal

Enables an entity to be used within the defining module (target). You typically use internal access when defining an app’s or a framework’s internal structure.

// First.framework – A.swift

internal struct A {}

// First.framework – B.swift

A() // ok

// Second.framework – C.swift

import First

A() // error: A is unavailable

3. fileprivate

Restricts the use of an entity to its defining source file. You typically use fileprivate access to hide the implementation details of a specific piece of functionality when those details are used within an entire file.

// First.framework – A.swift

internal struct A {

fileprivate static let x: Int

}

A.x // ok

// First.framework – B.swift

A.x // error: x is not available

4. private

Restricts the use of an entity to its enclosing declaration. You typically use private access to hide the implementation details of a specific piece of functionality when those details are used only within a single declaration.

// First.framework – A.swift

internal struct A {

private static let x: Int

internal static func doSomethingWithX() {
x // ok
}

}

A.x // error: x is unavailable

Internal vs. Private Access Modifiers

internal is for assembly scope (i.e. only accessible from code in the same .exe or .dll)

private is for class scope (i.e. accessible only from code in the same class).

Swift: access level between `private` and `internal`?

As others have said, there is no way to do exactly what you want today in Swift.

One alternative is to use an extension in another file to add GridControllerModel as a nested subtype of GridController. e.g.

//GridControllerModel.swift

extension GridController {
struct GridControllerModel {
let propertyOne:String
let propertyTwo:String
}
}

This allows your GridController class in its own separate file to declare something like:

var model = GridControllerModel()

However, the rest of the application can still access the GridControllerModel type like this:

//SomeOtherClass.swift

var nested = GridController.GridControllerModel()

So, you do achieve some separation by making the model type a subtype of GridController, but it isn't true access control. On the plus side, it will not appear in code completion outside of the GridController class as "GridControllerModel", you would need to first type "GridController" and then "." to see the subtype "GridController.GridControllerModel"

It's also worth noting that an additional access control level is currently under review and likely to be in the next version of Swift (3.0) :

https://github.com/apple/swift-evolution/blob/master/proposals/0025-scoped-access-level.md

Assuming this proposal is accepted and implemented, you would be able to update your declared subtype like this:

//GridControllerModel.swift

local extension GridController {
struct GridControllerModel {
let propertyOne:String
let propertyTwo:String
}
}

(Note the "local" keyword above now). This would make the GridControllerModel type invisible and inaccessible to all classes except GridController and any extensions of GridController.

So, I would recommend that you consider this nested subtype approach today, because when Swift 3.0 arrives later this year, it's likely to support what you want by simply adding a keyword in front of your subtype declaration. And in the meantime, you get some of the separation you want as well.

What is the difference between public, protected, package-private and private in Java?

The official tutorial may be of some use to you.

















































ClassPackageSubclass
(same pkg)
Subclass
(diff pkg)
World
public+++++
protected++++
no modifier+++
private+

Difference between internal and moduleprivate in Swift

There is no difference conceptually; moduleprivate was just a possible alternate name for the same access level that didn't get accepted during discussions about access control modifier naming.

https://lists.swift.org/pipermail/swift-evolution/Week-of-Mon-20160328/013854.html

The internal modifier is the only one of the two that actually exists in the Swift language, but the two names represent the same behavior.

Difference between fileprivate and private extension?

The difference only crops up when we are talking about type members. private will restrict access to other methods within the same type definition, while fileprivate things are accessible by anything that lives in the same .swift file.

For things that live at the top level (outside of a type definition), private and fileprivate do exactly the same thing. So when you write

fileprivate extension Foo 
{
var aa: Int
{
return aaa + 10
}
}

private extension Foo
{
var aaa: Int
{
return 20
}
}

You really wrote

fileprivate extension Foo 
{
var aa: Int
{
return aaa + 10
}
}

fileprivate extension Foo
{
var aaa: Int
{
return 20
}
}

Ultimately, the two extensions on the same protocol get resolved by the compiler into a single extension.

fileprivate extension Foo 
{
var aa: Int
{
return aaa + 10
}
var aaa: Int
{
return 20
}
}

If you think think having two keywords like this is stupid, some Swift architects agree with you. I believe some style guides recommend you only bother using the public and private access modifiers (as well as the internal modifier, but that one is by default) because, in general, restricting things on a per-file basis, as opposed to a per-module or per-type basis is not particularly useful.

If you must use the fileprivate modifier, then never use the private modifier outside of a type scope. It’s confusing (since the private in that context “really” means fileprivate) and makes your code harder to read.



Related Topics



Leave a reply



Submit