Let's create our first program on Linux using Swift. Our first project will be a package. Create a directory named guesswho
and then enter the directory:
$ mkdir guesswho
$ cd guess who
Next we need to initialize a new package with the type being an executable:
$ swift package init --type executable
Creating executable package: guesswho
Creating Package.swift
Creating .gitignore
Creating Sources/
Creating Sources/main.swift
Creating Tests/
I want to point out a couple of things about the output of swift package init. First, using the swift package init command is optional and meant only to be a utility mechanism for generating files and directories you may need. Second, the package manager expects you to put your sources files within the Sources directory. You can further nest additional directories under theĀ Sources
directory and the package manager will treat those directories as modules. Finally, when you want to create an executable, you need to include a main.swift
file in the module's subdirectory or directly within the Sources
directory in cases when you only have one target. Let's look at an example of a Swift package.
Creating a package with multiple modules:
mymodule/Sources/worker/workerbot.swift
mymodule/Sources/manager/manager.swift
Running swift build on the package above creates:
mymodule/.build/debug/workerbot.a
mymodule/.build/debug/manager.a
Creating a package with one executable and one library module:
mymodule/Sources/worker/main.swift
mymodule/Sources/manager/manager.swift
Running swift build in this time would result in:
mymodule/.build/debug/workerbot
mymodule/.build/debug/manager.a
Notice that our executable doesn't have an extension; however, our library file is created with a
.a
extension.
Open main.swift and remove the code that is currently in there. We are going to replace the existing code with some new logic.
Let's add a function that will recursively call itself and remove the first letter of its input string from the remaining characters, repeating the task until there are no letters left in the string. Once we are finished, we execute a closure to let the caller know we are done:
func breakWord(combine result:String, input:String, done:(String?)->Void){ let characterArray = input.characters let breakoutCharacter = characterArray.first let remainingCharacters = characterArray.dropFirst() if characterArray.count > 0{ let line = "\n\(breakoutCharacter!): \(String(remainingCharacters)) " let newResult = "\(result) \(line)" breakWord(combine: newResult, input: String(remainingCharacters), done: done) return } done(result) }
Next we need to handle the arguments passed when executing our swift program. First in line 1, we store the argument lists as an array. Next, in line 2 we check to make sure we have at least one argument that we can process using our breakWord(combine:)
function. Lines 3-8 iterate over our argument list and call ourbreakWord(combine:)
function for each argument. In line 4, we use a closure expression to print the final result of our breakWord(combine:)
routine:
let arguments = Process.arguments if arguments.count > 1{ for n in 1..<arguments.count{ breakWord(combine: "", input: arguments[n]){ (result) in print(result!) } } } else{ print("no arguments passed") }
Close and save main.swift
and then compile the program using swift build. You can execute the program by typing guesswho
along with one or more arguments:
$ .build/debug/guesswho Swift 3 New Features S: wift w: ift i: ft f: t t: 3: N: ew e: w w: F: eatures e: atures a: tures t: ures u: res r: es e: s s: