Точка входа в программу представляет функцию, с которой начинается выполнение приложения. Для определения функции как точки входа в приложения, применяются ряд условий:
Эта функция должна применять атрибут [<EntryPoint>]
Эта функция должна принимать один параметр - набор (а точнее массив) строк, через которые в данную функцию можно передать данные при ее вызове. (Например, при запуске приложения из командной строки)
Эта функция должна возвращать число типа int. Согласно условностям, обычно это 0 - при успешном выполнении, либо любое другое число при неудачном выполнении.
Эта функция должна быть последней функцией в последнем компилируемом файле.
(Последний компилируемый файл - это последний файл в проекте, либо последний файл в списке файлов, которые передаются компилятору при компиляции в командной строке)
Как правило, эта функция называеся main, но это необязательно. Например, определим в проекте в главном файле программы Program.fs следующий код:
[<EntryPoint>]
let main argv =
printfn "Функция main"
0
Итак, данная функция применяет атрибут [<EntryPoint>] (он указывается над определением функции). Она имеет один параметр и возвращает число.
Запустим проект на выполнение с помощью dotnet run:
C:\Users\eugen\fsharp\helloapp>dotnet run Функция main C:\Users\eugen\fsharp\helloapp>
По умолчанию при написании программы нам необязательно определять функцию-точку входа в программу, так как мы можем использовать так называемые программы верхнего уровня или top level statements, когда мы сразу можем вызывать инструкции вне какой-либо функции.
Стоит отметить, что если параметр функции не используется, мы можем, как в общем случае, вместо него указать прочерк:
[<EntryPoint>]
let main _ =
printfn "Функция main"
0
Теперь обратимся к последнему условию: функция входа в приложение должна быть последней функций (и вообще последним опредлением в файле). То есть мы можем разместить другие конструкции, определения значений, функций, их вызов до функции main:
let sum x y = x + y
let message = "Hello F#"
printfn $"{message}"
[<EntryPoint>]
let main _ =
printfn "Функция main"
0
Но мы НЕ можем это сделать после определения функции входа в приложение:
[<EntryPoint>]
let main _ =
printfn "Функция main"
0
let sum x y = x + y
let message = "Hello F#"
printfn $"{message}"
Но в принципе в этом случае компилятор укажет на ошибку.
Стоит отметить, что если до функции точки входа в приложение идут вызовы других функций, то они также выполняются. В данном случае имеются ввиду вызовы функций верхнего уровня - то есть такие вызовы функций, которые расположены вне других функций. Например, путь у нас будет следующий код программы:
let sum x y = x + y
let message = "Hello F#"
printfn $"{message}"
printfn $"Сумма 1 и 2 равна {sum 1 2}"
[<EntryPoint>]
let main _ =
printfn "Функция main"
0
В данном случае мы получим следующий консольный вывод:
Hello F# Сумма 1 и 2 равна 3 Функция main
Таким образом, мы видим, что все выражения, которые идут до функции main, также были выполнены.
Однако если до функции входа в приложение идут только определения функций без их вызовов, то эти функции не выполняются:
let sum x y = printfn $"Сумма {x} и {y} равна {x + y}"
let printMessage _ = printfn "Hello F#"
[<EntryPoint>]
let main _ =
printfn "Функция main"
0
Так, в данном случае будет выполняться только функция main, поскольку именно она является точкой входа в приложения. Соответственно консольный вывод программы:
Функция main
Чтобы выполнить подобные функции, нам надо вызвать их в функции main:
let sum x y = printfn $"Сумма {x} и {y} равна {x + y}"
let printMessage _ = printfn "Hello F#"
[<EntryPoint>]
let main _ =
printfn "Функция main"
sum 1 2
printMessage()
0
Консольный вывод программы:
Функция main Сумма 1 и 2 равна 3 Hello F#
Выше было показано, как определять точку входа, однако в предыдущих статьях точка входа не использовалась, но код тем не менее выполнялся. Если в коде явным образом не определено функции с атрибутом EntryPoint, то в качестве точки входа используются все привязки значений и функций верхнего уровня, которые определены в последнем компилируемом файле.