我想使用defmacro来计算数字列表的平均值。它应该像这样运行:
Internal .Net Framework Data Provider error 6.
Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.InvalidOperationException: Internal .Net Framework Data Provider error 6.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[InvalidOperationException: Internal .Net Framework Data Provider error 6.]
System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, UInt32 waitForMultipleObjectsTimeout, Boolean allowCreate, Boolean onlyOneCheckConnection, DbConnectionOptions userOptions, DbConnectionInternal& connection) +347
System.Data.ProviderBase.DbConnectionPool.TryGetConnection(DbConnection owningObject, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal& connection) +78
System.Data.ProviderBase.DbConnectionFactory.TryGetConnection(DbConnection owningConnection, TaskCompletionSource`1 retry, DbConnectionOptions userOptions, DbConnectionInternal oldConnection, DbConnectionInternal& connection) +191
System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions) +154
System.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions) +21
System.Data.SqlClient.SqlConnection.TryOpenInner(TaskCompletionSource`1 retry) +90
System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry) +217
System.Data.SqlClient.SqlConnection.Open() +96
System.Data.Entity.Infrastructure.Interception.DbConnectionDispatcher.<Open>b__36(DbConnection t, DbConnectionInterceptionContext c) +10
System.Data.Entity.Infrastructure.Interception.InternalDispatcher`1.Dispatch(TTarget target, Action`2 operation, TInterceptionContext interceptionContext, Action`3 executing, Action`3 executed) +72
System.Data.Entity.Infrastructure.Interception.DbConnectionDispatcher.Open(DbConnection connection, DbInterceptionContext interceptionContext) +360
System.Data.Entity.Core.EntityClient.EntityConnection.<Open>b__2() +55
System.Data.Entity.SqlServer.<>c__DisplayClass1.<Execute>b__0() +10
System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute(Func`1 operation) +189
System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute(Action operation) +78
System.Data.Entity.Core.EntityClient.EntityConnection.Open() +253
[EntityException: The underlying provider failed on Open.]
System.Data.Entity.Core.EntityClient.EntityConnection.Open() +323
System.Data.Entity.Core.Objects.ObjectContext.EnsureConnection(Boolean shouldMonitorTransactions) +133
System.Data.Entity.Core.Objects.ObjectContext.ExecuteInTransaction(Func`1 func, IDbExecutionStrategy executionStrategy, Boolean startLocalTransaction, Boolean releaseConnectionOnSuccess) +46
System.Data.Entity.Core.Objects.<>c__DisplayClass7.<GetResults>b__5() +154
System.Data.Entity.SqlServer.DefaultSqlExecutionStrategy.Execute(Func`1 operation) +189
System.Data.Entity.Core.Objects.ObjectQuery`1.GetResults(Nullable`1 forMergeOption) +279
System.Data.Entity.Core.Objects.ObjectQuery`1.<System.Collections.Generic.IEnumerable<T>.GetEnumerator>b__0() +11
System.Data.Entity.Internal.LazyEnumerator`1.MoveNext() +45
System.Linq.Enumerable.FirstOrDefault(IEnumerable`1 source) +121
System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.<GetElementFunction>b__1(IEnumerable`1 sequence) +40
System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.ExecuteSingle(IEnumerable`1 query, Expression queryRoot) +60
System.Data.Entity.Core.Objects.ELinq.ObjectQueryProvider.System.Linq.IQueryProvider.Execute(Expression expression) +113
System.Data.Entity.Internal.Linq.DbQueryProvider.Execute(Expression expression) +113
System.Linq.Queryable.FirstOrDefault(IQueryable`1 source) +211
System.Data.Entity.Internal.EdmMetadataRepository.QueryForModelHash(Func`2 createContext) +285
System.Data.Entity.Internal.InternalContext.QueryForModelHash() +198
System.Data.Entity.Internal.ModelCompatibilityChecker.CompatibleWithModel(InternalContext internalContext, ModelHashCalculator modelHashCalculator, Boolean throwIfNoMetadata, DatabaseExistenceState existenceState) +84
System.Data.Entity.Internal.InternalContext.CompatibleWithModel(Boolean throwIfNoMetadata, DatabaseExistenceState existenceState) +54
System.Data.Entity.CreateDatabaseIfNotExists`1.InitializeDatabase(TContext context) +117
System.Data.Entity.Internal.<>c__DisplayClassf`1.<CreateInitializationAction>b__e() +76
System.Data.Entity.Internal.InternalContext.PerformInitializationAction(Action action) +60
[DataException: An exception occurred while initializing the database. See the InnerException for details.]
System.Data.Entity.Internal.InternalContext.PerformInitializationAction(Action action) +122
System.Data.Entity.Internal.InternalContext.PerformDatabaseInitialization() +357
System.Data.Entity.Internal.LazyInternalContext.<InitializeDatabase>b__4(InternalContext c) +7
System.Data.Entity.Internal.RetryAction`1.PerformAction(TInput input) +110
System.Data.Entity.Internal.LazyInternalContext.InitializeDatabaseAction(Action`1 action) +198
System.Data.Entity.Internal.LazyInternalContext.InitializeDatabase() +73
System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType) +28
System.Data.Entity.Internal.Linq.InternalSet`1.Initialize() +53
System.Data.Entity.Internal.Linq.InternalSet`1.get_InternalContext() +15
System.Data.Entity.Internal.Linq.InternalSet`1.ExecuteSqlQuery(String sql, Boolean asNoTracking, Nullable`1 streaming, Object[] parameters) +96
System.Data.Entity.Internal.InternalSqlSetQuery.GetEnumerator() +42
System.Data.Entity.Infrastructure.DbRawSqlQuery`1.GetEnumerator() +30
System.Collections.Generic.List`1..ctor(IEnumerable`1 collection) +369
System.Linq.Enumerable.ToList(IEnumerable`1 source) +58
Login.Controllers.HomeController.Index(String error) +283
lambda_method(Closure , ControllerBase , Object[] ) +104
System.Web.Mvc.ActionMethodDispatcher.Execute(ControllerBase controller, Object[] parameters) +14
System.Web.Mvc.ReflectedActionDescriptor.Execute(ControllerContext controllerContext, IDictionary`2 parameters) +182
System.Web.Mvc.ControllerActionInvoker.InvokeActionMethod(ControllerContext controllerContext, ActionDescriptor actionDescriptor, IDictionary`2 parameters) +27
System.Web.Mvc.Async.<>c__DisplayClass42.<BeginInvokeSynchronousActionMethod>b__41() +28
System.Web.Mvc.Async.<>c__DisplayClass8`1.<BeginSynchronous>b__7(IAsyncResult _) +10
System.Web.Mvc.Async.WrappedAsyncResult`1.End() +50
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethod(IAsyncResult asyncResult) +32
System.Web.Mvc.Async.<>c__DisplayClass39.<BeginInvokeActionMethodWithFilters>b__33() +58
System.Web.Mvc.Async.<>c__DisplayClass4f.<InvokeActionMethodFilterAsynchronously>b__49() +225
System.Web.Mvc.Async.<>c__DisplayClass37.<BeginInvokeActionMethodWithFilters>b__36(IAsyncResult asyncResult) +10
System.Web.Mvc.Async.WrappedAsyncResult`1.End() +50
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeActionMethodWithFilters(IAsyncResult asyncResult) +34
System.Web.Mvc.Async.<>c__DisplayClass2a.<BeginInvokeAction>b__20() +24
System.Web.Mvc.Async.<>c__DisplayClass25.<BeginInvokeAction>b__22(IAsyncResult asyncResult) +99
System.Web.Mvc.Async.WrappedAsyncResult`1.End() +50
System.Web.Mvc.Async.AsyncControllerActionInvoker.EndInvokeAction(IAsyncResult asyncResult) +27
System.Web.Mvc.<>c__DisplayClass1d.<BeginExecuteCore>b__18(IAsyncResult asyncResult) +14
System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +16
System.Web.Mvc.Async.WrappedAsyncResult`1.End() +50
System.Web.Mvc.Controller.EndExecuteCore(IAsyncResult asyncResult) +36
System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +16
System.Web.Mvc.Async.WrappedAsyncResult`1.End() +50
System.Web.Mvc.Controller.EndExecute(IAsyncResult asyncResult) +26
System.Web.Mvc.Controller.System.Web.Mvc.Async.IAsyncController.EndExecute(IAsyncResult asyncResult) +10
System.Web.Mvc.<>c__DisplayClass8.<BeginProcessRequest>b__3(IAsyncResult asyncResult) +25
System.Web.Mvc.Async.<>c__DisplayClass4.<MakeVoidDelegate>b__3(IAsyncResult ar) +16
System.Web.Mvc.Async.WrappedAsyncResult`1.End() +50
System.Web.Mvc.MvcHandler.EndProcessRequest(IAsyncResult asyncResult) +28
System.Web.Mvc.MvcHandler.System.Web.IHttpAsyncHandler.EndProcessRequest(IAsyncResult result) +9
System.Web.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +9644037
System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +155
我的代码是:
user=> (avg 1 2 3 4 5 6)
3.5
但是我收到了一个错误:
(defmacro ave [& number]
`(float `(/ `(reduce + ~number) `(count ~number))))
我该如何解决?感谢
答案 0 :(得分:2)
正如合金建议的那样,最好的解决方案是功能:
(ns clj.core
(:require [clojure.string :as str] )
(:use tupelo.core))
(defn avg
"Compute the average of 1 or more vals."
[& values]
(when (zero? (count values))
(throw (IllegalArgumentException. "avg: error - at least 1 value required")))
(let [total (apply + values)
result (double (/ total (count values))) ]
result))
它的测试:
(ns tst.clj.core
(:use clj.core
clojure.test
tupelo.core))
(deftest t-avg
(is (thrown? IllegalArgumentException (avg)))
(is (= 1.0 (avg 1)))
(is (= 1.5 (avg 1 2)))
(is (= 2.0 (avg 1 2 3)))
(is (= 2.5 (avg 1 2 3 4))))
请注意,该函数比宏更强大,因为宏不能作为参数传递给高阶函数(例如滤镜,贴图等)。
答案 1 :(得分:1)
你应该使用一个包含整个表达式的语法引用,并将你的数字的unquote-splicing作为list参数。除此之外,由于reduce
和count
接受列表作为参数,我使用list
来包装它们。所以,试试:
(defmacro ave [& number]
`(float(/ (reduce + (list ~@number)) (count (list ~@number)))))
在REPL中产生:
user=> (ave 1 2 3 4 5 6)
3.5
更新:根据评论中amalloy指出的错误,这是我的第二个版本:
(defmacro ave [& number]
`(let [ns# (list ~@number)]
(float (/ (reduce + ns#) (count ns#)))))
我在REPL中的测试:
user=> (ave (do (println "Doing a lot of work...") 1) 2 3 4 5 6)
Doing a lot of work...
3.5